ORA-01722: неверный номер в подзапросе - PullRequest
0 голосов
/ 03 февраля 2020

Привет, я пытаюсь выполнить свой запрос и, к сожалению, выдает мне ошибку ORA-01722: неверный номер

SELECT L.NEVENTLOGIDN, LPAD (nuserid, 6, '0') nuserid, u.susername, 
  TO_CHAR (TO_DATE ('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + ( (ndatetime) / (60 * 60 * 24)), 'YYYY-MM-DD HH24:MI:SS') 
  date_time, l.nreaderidn, r.sname, 
  CASE WHEN l.nreaderidn IN (SELECT GETREADERSBYFUNC('OUT', 'LOCKER') devices FROM dual ) THEN 'O' 
  WHEN l.nreaderidn IN (SELECT GETREADERSBYFUNC('IN', 'LOCKER') devices FROM dual ) THEN 'I' END logtype 
  FROM TB_EVENT_LOG l, TB_READER r, TB_USER u 
  WHERE 
  l.nreaderidn IN ( SELECT GETREADERSBYDESC('LOCKER') devices FROM dual) 
  AND NDATETIME >= ((TO_DATE ('2020-01-27' || ' 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM') ) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60 
  AND ndatetime <= ((TO_DATE ('2020-01-28' || ' 12:00:00 PM', 'YYYY-MM-DD HH:MI:SS PM') ) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60 
  AND l.nuserid = u.suserid 
  AND l.nreaderidn = r.nreaderidn 
  ORDER BY 2, 4

Я думаю, что причина ошибки в следующем.

1

CASE WHEN l.nreaderidn IN (SELECT GETREADERSBYFUNC('OUT', 'LOCKER') devices FROM dual ) THEN 'O'

пример данных GetReaderbyfun c

'544381428','544381436','544381433','544381424','544381043'

2

  WHEN l.nreaderidn IN (SELECT GETREADERSBYFUNC('IN', 'LOCKER') devices FROM dual ) THEN 'I' END logtype

3

WHERE 
  l.nreaderidn IN ( SELECT GETREADERSBYDESC('LOCKER') devices FROM dual) 


SELECT GETREADERSBYFUNC('OUT', 'LOCKER') devices FROM dual 

результат ниже

'544381428','544381436','544381433','544381424','544381043'

, потому что nreaderidn - это числовой тип, но когда я ставлю его результат, как показано ниже, он работает

SELECT GETREADERSBYDESC('LOCKER') devices FROM dual

результат - ниже

'544381050','544381441','544381428','544381436','544381431','544381064','544381433','544381435','544381424','544381043'



WHERE 
  l.nreaderidn IN ( '544381428','544381436','544381433','544381424','544381043')

функции

getreadersbyfunc (p_func VARCHAR2, p_desc VARCHAR2)
 RETURN VARCHAR2
IS
   retVal VARCHAR2(1024);
BEGIN

   for cur_rec in (SELECT nreaderidn FROM tb_reader where sdescription = p_desc and upper(sname) like '%' || upper(p_func) || '%') 
   loop
        if retVal is NULL then
            retVal := '''' || cur_rec.nreaderidn || '''';
        else
            retVal := retVal || ',''' || cur_rec.nreaderidn || '''';
        end if;
   end loop;

   return retVal;


   EXCEPTION
   WHEN NO_DATA_FOUND THEN
       NULL;
   WHEN OTHERS THEN
       RAISE;


getreadersbydesc (p_description VARCHAR2)
   RETURN VARCHAR2
IS
   retVal VARCHAR2(1024);
BEGIN

   for cur_rec in (SELECT nreaderidn FROM tb_reader where sdescription = p_description) 
   loop
        if retVal is NULL then
            retVal := '''' || cur_rec.nreaderidn || '''';
        else
            retVal := retVal || ',''' || cur_rec.nreaderidn || '''';
        end if;
   end loop;

   return retVal;


   EXCEPTION
   WHEN NO_DATA_FOUND THEN
       NULL;
   WHEN OTHERS THEN
       RAISE;
END;

Мне не разрешено изменять тип данных nreaderidn и изменять функцию oracle. Есть ли способ решить это? Заранее спасибо

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Ваша функция возвращает разделенный запятыми список чисел, который необходимо разделить. Попробуйте th

Например:

SELECT 
   regexp_substr(GETREADERSBYFUNC('OUT', 'LOCKER'), '[^,]+', 1, level)  
FROM dual 
  connect by 
  regexp_substr(GETREADERSBYFUNC('OUT', 'LOCKER'), '[^,]+', 1, level) is not null

Ваш запрос будет выглядеть следующим образом:

SELECT L.NEVENTLOGIDN, LPAD (nuserid, 6, '0') nuserid, u.susername, 
  TO_CHAR (TO_DATE ('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + ( (ndatetime) / (60 * 60 * 24)), 'YYYY-MM-DD HH24:MI:SS') 
  date_time, l.nreaderidn, r.sname, 
  CASE WHEN l.nreaderidn IN (SELECT 
regexp_substr(GETREADERSBYFUNC('OUT', 'LOCKER'), '[^,]+', 1, level) FROM dual 
  connect by regexp_substr(GETREADERSBYFUNC('OUT', 'LOCKER'), '[^,]+', 1, level) is not null ) THEN 'O' 
  WHEN l.nreaderidn IN (SELECT 
   regexp_substr(GETREADERSBYFUNC('IN', 'LOCKER'), '[^,]+', 1, level) FROM dual 
  connect by  regexp_substr(GETREADERSBYFUNC('IN', 'LOCKER'), '[^,]+', 1, level) is not null) THEN 'I' END logtype 
  FROM TB_EVENT_LOG l, TB_READER r, TB_USER u 
  WHERE 
  l.nreaderidn IN ( SELECT 
   regexp_substr(GETREADERSBYFUNC('LOCKER'), '[^,]+', 1, level)  FROM dual 
  connect by  regexp_substr(GETREADERSBYFUNC('LOCKER'), '[^,]+', 1, level) is not null) 
  AND NDATETIME >= ((TO_DATE ('2020-01-27' || ' 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM') ) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60 
  AND ndatetime <= ((TO_DATE ('2020-01-28' || ' 12:00:00 PM', 'YYYY-MM-DD HH:MI:SS PM') ) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60 
  AND l.nuserid = u.suserid 
  AND l.nreaderidn = r.nreaderidn 
  ORDER BY 2, 4
0 голосов
/ 03 февраля 2020

Это не приведет к ошибке:

SELECT * 
from TB_READER l
where cast(l.nreaderidn as varchar2(1024)) in (select GETREADERSBYDESC('LOCKER') devices FROM dual)

Просто используйте cast столбца nreaderidn.

Но также имейте в виду, что вы будете искать varchar, например «2» в строке (не последовательность символов, а одна строка) «1», «2», «3», так что это не будет Повторите любые результаты.

Вот также небольшой пример, где вы можете увидеть, как ошибка была произведена без приведения и решена при добавлении приведения:

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=776ecd951aff56500938ac064b34788c

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...