IN-Condition类型转换似乎是错误的

时间:2017-08-08 08:43:52

标签: oracle

我有一张圆柱ErrorID的表格。由于历史原因,此ID为Tye VARCHAR2 (30 CHAR),并对应用程序运行时期间发生的错误进行编码。

ErrorID | Meaning
------------------------
01      | no error
02      | wrong password
...
99      | unknown
ERROR   | unknown

要检查是否发生严重错误,请使用以下查询:

SELECT ThreadID, CASE WHEN ErrorID IN ('05','06') THEN 'Yes' ELSE 'NO' END AS "Critical"
FROM ErrorTable

结果始终为No。如果我将查询更改为

SELECT ThreadID, CASE WHEN ErrorID IN (05, 06) THEN 'Yes' ELSE 'NO' END AS "Critical"
FROM ErrorTable

结果是正确的,即右侧线程中的YesNo

我已经读过,Oracle会将'10'转换为NUMBER数据类型,如果它出现在数值表达式中,但在我的情况下,ErrorIDVARCHAR2可以是一个真正的字符串(参见示例表中的最后一项)。

为什么Oracle的行为如此?我认为这是非常危险的,因为我告诉我的客户"测试过程中没有出现严重错误"尽管他们确实......

更新 正如评论中所希望的那样,这里是实际输出。由于数据保护法,限制了感兴趣的列:

DESC ErrorTable
Name                         Null     Typ                 
---------------------------- -------- ------------------- 
ThreadID                     NOT NULL NUMBER(38)          
...
ErrorID                               VARCHAR2(30 CHAR) 

SELECT * FROM ErrorTable WHERE ThreadID = 8917
THREADID | ... | ERRORID
------------------------
8917     | ... | 01 

SELECT ThreadID, CASE WHEN ErrorID IN ('1','01') THEN 'Yes' ELSE 'No' END AS "Critical" FROM ErrorTable WHERE ThreadID = 8917;
THREADID | CRITICAL
--------------------
8917     | No  

SELECT ThreadID, CASE WHEN ErrorID IN (01) THEN 'Yes' ELSE 'No' END AS "Critical" FROM ErrorTable WHERE ThreadID = 8917;
THREADID | CRITICAL
------------------------
8917     | Yes

1 个答案:

答案 0 :(得分:0)

Oracle数据库的行为与断言不同。 in ('05', '06')将匹配相关的行。 in (05, 06)会抛出ORA-01722,因为'ERROR'无法转换为数字。

最可能的解释是ERROR ID不是您认为的。也许你有尾随空格? '05 ' != '05'。虽然你仍然应该得到ORA-01722错误。

如果这不能帮助您发布可重现的测试用例:表结构,示例数据,演示问题的查询。