问题描述
我有一个查询,我试图通过过滤nvarchar2(2000) 列返回一个id。如果我硬编码过滤条件之一,查询返回所需的输出,但使用子查询时,我得到ORA-01858错误:
此查询返回正确的结果:
选择 * 从 (
选择atrb_val_tx作为atrb_val_tx
从表1 a1
其中atrb_id在 (666,669,672,675,688,694)
和is_actv_fl = 1) a1
其中,to_date(regexp_substr(a1.atrb _ val_tx,'[^ |] ',1),'MM/DD/yyy') <= TO_DATE('10/11/2016','MM/DD/yyy');
但是当像这样替换WHERE子句中的第一个语句时,它返回ORA-01858
(注意两个内联视图返回相同的数据):
选择 * 从 (
选择atrb_val_tx作为atrb_val_tx
从表1 a1
其中atrb_id在 (从表2中选择atrb_id,其中ctrl_type_id = 10)
和is_actv_fl = 1) a1
其中,to_date(regexp_substr(a1.atrb _ val_tx,'[^ |] ',1),'MM/DD/yyy') <= TO_DATE('10/11/2016','MM/DD/yyy');
此查询返回正确的结果:
选择 * 从 (
选择atrb_val_tx作为atrb_val_tx
从表1 a1
其中atrb_id在 (666,669,672,675,688,694)
和is_actv_fl = 1) a1
其中,to_date(regexp_substr(a1.atrb _ val_tx,'[^ |] ',1),'MM/DD/yyy') <= TO_DATE('10/11/2016','MM/DD/yyy');
但是当像这样替换WHERE子句中的第一个语句时,它返回ORA-01858
(注意两个内联视图返回相同的数据):
选择 * 从 (
选择atrb_val_tx作为atrb_val_tx
从表1 a1
其中atrb_id在 (从表2中选择atrb_id,其中ctrl_type_id = 10)
和is_actv_fl = 1) a1
其中,to_date(regexp_substr(a1.atrb _ val_tx,'[^ |] ',1),'MM/DD/yyy') <= TO_DATE('10/11/2016','MM/DD/yyy');
专家解答
你依赖谓词评估的顺序,这是一件冒险的事情。这是一个简单的例子,可能会出错
您可以添加一些 “安全” 条款来帮助您,例如
SQL> create table t ( x int, y varchar2(20));
Table created.
SQL>
SQL> insert into t values (1, '01/01/2000');
1 row created.
SQL> insert into t values (2, 'garbage');
1 row created.
SQL>
SQL> select *
2 from t
3 where to_date(y,'dd/mm/yyyy') < sysdate
4 and x = 1;
X Y
---------- --------------------
1 01/01/2000
1 row selected.
SQL>
SQL> select *
2 from t
3 where to_date(y,'dd/mm/yyyy') < sysdate
4 and x = ( select count(*) from dual );
ERROR:
ORA-01858: a non-numeric character was found where a numeric was expected
您可以添加一些 “安全” 条款来帮助您,例如
SQL> select *
2 from t
3 where ( y like '__/__/____' and to_date(y,'dd/mm/yyyy') < sysdate )
4 and x = ( select count(*) from dual );
X Y
---------- --------------------
1 01/01/2000
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




