如何解决使用/不使用 CASE 语句时,Oracle NVL 返回不一致结果
任何人都可以帮助我理解为什么 oracle db 在使用/不使用 CASE 语句时返回不一致的结果。
SELECT NVL(CASE WHEN '' IS NULL THEN NULL ELSE NULL END,TO_DATE('19010101','YYYYMMDD')) a,NVL(CASE WHEN '' IS NOT NULL THEN NULL ELSE NULL END,'YYYYMMDD')) b,NVL(CASE WHEN '' = '' THEN NULL ELSE NULL END,'YYYYMMDD')) c,NVL(NULL,'YYYYMMDD')) d from dual;
我的实际查询使用 TRUNC(NVL(:NEW_FORM_TIME_END,'YYYYMMDD'))) >= TRUNC(SYSDATE - INTERVAL '2' DAY)
其中 NEW_FORM_TIME_END
可能是空字符串或 NULL 但我收到此错误 ORA-06550: line 240,column 91: PLS-00306: wrong number or types of arguments in call to '>=' ORA-06550: line 229,column 9: PL/SQL: Statement ignored
解决方法
您的 case 表达式属于 VARCHAR2
类型,如果您不提供显式类型,则这是默认类型。 NULL
文字没有类型。 NVL(<varchar2>,<date>)
对 <date>
参数应用隐式类型转换。在其他 RDBMS 中,您只会因为类型不兼容而得到错误。您的表达式的 PL/SQL 版本可能也存在类似的问题,尽管与您在查询中呈现的不完全相同。
只要确保你总是比较相同的类型。
试试这个来检查:
SELECT
NVL(CAST(CASE WHEN '' IS NULL THEN NULL END AS DATE),DATE '1901-01-01') a,NVL(CAST(CASE WHEN '' IS NOT NULL THEN NULL END AS DATE),DATE '1901-01-01') b,NVL(CAST(CASE WHEN '' = '' THEN NULL END AS DATE),DATE '1901-01-01') c,NVL(NULL,DATE '1901-01-01') d
FROM dual;
或者,从您的表创建一个视图,然后检查字典:
CREATE VIEW v AS
SELECT
NVL(CASE WHEN '' IS NULL THEN NULL END,NVL(CASE WHEN '' IS NOT NULL THEN NULL END,NVL(CASE WHEN '' = '' THEN NULL END,TO_DATE('19010101','YYYYMMDD')) d
FROM dual;
SELECT column_name,data_type
FROM all_tab_cols
WHERE table_name = 'V'
ORDER BY column_name;
产量
|COLUMN_NAME|DATA_TYPE|
|-----------|---------|
|A |VARCHAR2 |
|B |VARCHAR2 |
|C |VARCHAR2 |
|D |DATE |
,
让我们分析所有这些:
NVL(CASE WHEN '' IS NULL THEN NULL ELSE NULL END,'YYYYMMDD'))
这应该返回 TO_DATE('19010101','YYYYMMDD'))
,因为 ''
与 Oracle 中的 NULL
相同,并且返回 THEN NULL
分支。
NVL(CASE WHEN '' IS NOT NULL THEN NULL ELSE NULL END,'YYYYMMDD'))
这个也应该返回 TO_DATE('19010101','YYYYMMDD')) since
'' IS NOT NULLis
false and the
ELSE NULL` 分支被返回。
NVL(CASE WHEN '' = '' THEN NULL ELSE NULL END,'YYYYMMDD'))
在 Oracle 中,'' = ''
转换为 NULL = NULL
,在 SQL 中计算为 NULL
,因此返回 `TO_DATE('19010101','YYYYMMDD'))。
NVL(NULL,'YYYYMMDD'))
这个也应该返回TO_DATE('19010101','YYYYMMDD'))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。