У меня проблема с преобразованием моего значения varchar2
в число. Проблема в том, что мой столбец TO_EMPLOYEE
(в PROJ_NOTIFY_HIST
) содержит как адреса электронной почты, так и идентификаторы сотрудников.
SELECT NOTIFY.PROJ_ID
FROM PROJ_NOTIFY_HIST NOTIFY
WHERE NOTIFY.NOTIFIED_SENT = 0
AND CAST(NOTIFY.TO_EMPLOYEE AS NUMBER) NOT IN (SELECT EMPLOYEE_ID
FROM V_ACTIVE_EMPLOYEE_INFO);
Есть ли способ получить только идентификаторы сотрудников и сравнить их с моим подзапросом?
Какую версию Oracle вы используете?
Вам нужно будет показать примеры TO_EMPLOYEE / EMPLOYEE_ID, я думаю, если один из них содержит «электронные письма и идентификаторы сотрудников»
Пожалуйста, проверьте свой Caps-Lock ключ, кажется, он сломан.
TO_EMPLOYEE содержит электронные письма и идентификаторы. (Тип данных: varchar)
EMPLOYEE_ID содержит только идентификаторы. (тип данных: число)
Таким образом, вам нужно извлечь идентификатор из TO_EMPLOYEE, для получения совета по этому поводу (помимо изменения структуры, так что в этом нет необходимости) вам нужно показать образцы данных, иначе на этот вопрос нет ответа.
Итак, вы ищете записи в текстовом поле, которые выглядят как идентификаторы сотрудников (только потому, что они числовые? Или есть ограничение на длину / формат?), Которые на самом деле не являются действительными идентификаторами - поскольку они не отображаются в активном сотруднике Посмотреть? Есть ли еще одна таблица / представление, в которой перечислены идентификаторы все?
Если вам нужно выполнить CAST столбец, как здесь, это указывает на плохой дизайн таблицы.
Используйте оператор case, чтобы проверить, преобразовывать ли вы его (поле состоит только из чисел) или нет.
CASE [ expression ]
WHEN condition_1 THEN result_1
ELSE result
END
Я подозреваю, что вам нужно что-то вроде этого:
SELECT NOTIFY.PROJ_ID
FROM PROJ_NOTIFY_HIST NOTIFY
WHERE NOTIFY.NOTIFIED_SENT = 0 AND
NOT EXIST (SELECT 1
FROM V_ACTIVE_EMPLOYEE_INFO A
WHERE TO_CHAR(A.EMPLOYEE_ID) = NOTIFY.TO_EMPLOYEE
);
Главное? Приведите к строке, а не к числу.
Если вы хотите ограничить это значениями, которые выглядят как числа, тогда:
SELECT NOTIFY.PROJ_ID
FROM PROJ_NOTIFY_HIST NOTIFY
WHERE NOTIFY.NOTIFIED_SENT = 0 AND
REGEXP_LIKE(EMPLOYEE_ID, '^[0-9]+$') AND
NOT EXIST (SELECT 1
FROM V_ACTIVE_EMPLOYEE_INFO A
WHERE TO_CHAR(A.EMPLOYEE_ID) = NOTIFY.TO_EMPLOYEE
);
Согласитесь с приведением к строке, а не к числу (ясно!); но это будет включать строки с адресами электронной почты, поскольку они также не будут соответствовать идентификатору активного сотрудника. Я не думаю, что OP хочет их видеть, просто идентификаторы, которые не активны. (Как это часто бывает, не совсем понятно ...)
Вы можете протестировать каждое значение to_employee
, чтобы увидеть, состоит ли оно только из числовых символов, и только затем попытаться преобразовать его в число и сравнить с вашим представлением. В последних версиях Oracle вы можете просто использовать to_number()
и использовать его предложение default ... on error
, чтобы предотвратить ORA-01722. Или validate_conversion()
, чтобы сделать тест.
Но это только скажет вам, является ли значение числовым, а не если это идентификатор сотрудника, который вы затем можете проверить, чтобы увидеть, активен ли он. У вас могут быть другие номера, которые не должны быть идентификаторами, например, номера телефонов.
если у вас есть таблица, содержащая все идентификаторы сотрудников, а не только активные, вы можете преобразовать их в другую сторону, от чисел к строкам, чтобы найти совпадения; например если у вас есть таблица employee_info
, содержащая всех активных и неактивных сотрудников, что-то вроде:
select notify.proj_id
from proj_notify_hist notify
join employee_info e
on notify.to_employee = cast(e.employee_id as varchar2(10)) -- use suitable size
where notify.notified_sent = 0
and e.employee_id not in (select employee_id
from v_active_employee_info);
или
select notify.proj_id
from proj_notify_hist notify
join employee_info e
on notify.to_employee = cast(e.employee_id as varchar2(10)) -- use suitable size
where notify.notified_sent = 0
and not exists (select null
from v_active_employee_info active
where active.employee_id = e.employee_id);
Если v_active_employee_info
представляет собой представление по таблице employee_info
, вы можете пропустить этот поиск по not in
или exists
и вместо этого напрямую проверить те условия, которые представление использует для фильтрации активных сотрудников.
Спасибо за помощь!
Тип данных столбца TO_EMPLOYEE?