Sql ORA-01722:子查询上的编号无效
嗨,我正在尝试执行我的查询,不幸的是,我遇到了错误ORA-01722:无效号码Sql ORA-01722:子查询上的编号无效,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,嗨,我正在尝试执行我的查询,不幸的是,我遇到了错误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,
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
GetReaderbyfunc的示例数据
'544381428','544381436','544381433','544381424','544381043'
二,
三,
结果如下
'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函数。
有办法解决这个问题吗?
提前感谢您的函数返回一个逗号分隔的数字列表,需要拆分。 试试看 例如: 您的查询将如下所示:
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
这不会给您一个错误:
SELECT *
from TB_READER l
where cast(l.nreaderidn as varchar2(1024)) in (select GETREADERSBYDESC('LOCKER') devices FROM dual)
只需使用nreaderidn列的强制转换
但也要注意,您将在字符串中搜索一个varchar,例如“2”,而不是一系列字符,而是一个字符串“1”、“2”和“3”,因此不会返回任何结果
这里还有一个小示例,您可以看到在没有强制转换的情况下生成errir,并在添加强制转换时解决:
它告诉我现在缺少表达式您的函数返回什么?不确定上面的查询中为什么有设备。你能单独运行并告诉我结果吗?选择castGETREADERSBYFUNC'OUT',LOCKER'as int FROM dual error表示SQL命令在尝试执行时未正确结束只需删除最后一个括号!!:从Dual中选择castGETREADERSBYFUNC'OUT',LOCKER'作为int。Oracle中的日期减法是number,然后将它们与日期列进行比较。因此,问题似乎出现在这里,而nDatime>=截止日期'2020-01-27'| |'12:00:00 AM',YYYY-MM-DD HH:MI:SS AM'-截止日期'1970-01-01 12:00:00 AM',YYYY-MM-DD HH:MI:SS AM'*24*60*60和nDatime我认为这不是我在子查询运行的位置上赋值的原因。因此,日期减法不是逐行注释,然后告诉您在查询的哪一行触发错误的原因。并不是说已经有100行了。见上文1、2、3对不起,我更新了我的问题
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;
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
SELECT *
from TB_READER l
where cast(l.nreaderidn as varchar2(1024)) in (select GETREADERSBYDESC('LOCKER') devices FROM dual)