Проблемы с преобразованием строк в числа

У меня проблема с преобразованием моего значения varchar2 в число. Проблема в том, что мой столбец TO_EMPLOYEEPROJ_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);

Есть ли способ получить только идентификаторы сотрудников и сравнить их с моим подзапросом?

Тип данных столбца TO_EMPLOYEE?

jarlh 10.08.2018 16:44

Какую версию Oracle вы используете?

APC 10.08.2018 16:44

Вам нужно будет показать примеры TO_EMPLOYEE / EMPLOYEE_ID, я думаю, если один из них содержит «электронные письма и идентификаторы сотрудников»

Alex K. 10.08.2018 16:44

Пожалуйста, проверьте свой Caps-Lock ключ, кажется, он сломан.

Wernfried Domscheit 10.08.2018 16:46

TO_EMPLOYEE содержит электронные письма и идентификаторы. (Тип данных: varchar)

DunDmy 10.08.2018 16:47

EMPLOYEE_ID содержит только идентификаторы. (тип данных: число)

DunDmy 10.08.2018 16:48

Таким образом, вам нужно извлечь идентификатор из TO_EMPLOYEE, для получения совета по этому поводу (помимо изменения структуры, так что в этом нет необходимости) вам нужно показать образцы данных, иначе на этот вопрос нет ответа.

Alex K. 10.08.2018 16:54

Итак, вы ищете записи в текстовом поле, которые выглядят как идентификаторы сотрудников (только потому, что они числовые? Или есть ограничение на длину / формат?), Которые на самом деле не являются действительными идентификаторами - поскольку они не отображаются в активном сотруднике Посмотреть? Есть ли еще одна таблица / представление, в которой перечислены идентификаторы все?

Alex Poole 10.08.2018 16:59

Если вам нужно выполнить CAST столбец, как здесь, это указывает на плохой дизайн таблицы.

jarlh 10.08.2018 17:06
1
9
77
3

Ответы 3

Используйте оператор 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 хочет их видеть, просто идентификаторы, которые не активны. (Как это часто бывает, не совсем понятно ...)

Alex Poole 10.08.2018 17:22

Вы можете протестировать каждое значение 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 и вместо этого напрямую проверить те условия, которые представление использует для фильтрации активных сотрудников.

Спасибо за помощь!

DunDmy 10.08.2018 21:12

Другие вопросы по теме