为啥 Oracle 的 DECODE 给我的价值与 NVL 不同?
Posted
技术标签:
【中文标题】为啥 Oracle 的 DECODE 给我的价值与 NVL 不同?【英文标题】:Why is Oracle's DECODE giving me a different value than NVL?为什么 Oracle 的 DECODE 给我的价值与 NVL 不同? 【发布时间】:2013-09-11 19:46:50 【问题描述】:这个查询:
select nvl(0.75,0) from dual
给我0.75
(数字)但是这个查询:
select decode(1,0,null,0.75) from dual
给我'.75'
(字符串)。
为什么?
我试图通过将第二个查询更改为:
select decode(1,0,null,to_char(0.75,'0.99')) from dual
但在我的实际代码中,0.75 将是一个可能有不同小数位数的字段 (NUMBER),我不打算从该值添加/删除任何内容。
关于如何解决丢失零问题但仍支持所有可能的十进制长度的任何想法?
【问题讨论】:
您应该尝试使用 Coalesce() 而不是 Nvl(),并使用 Case 而不是 Decode(),原因在别处解释了各种原因。 【参考方案1】:这是因为你的decode语句的第3个rd参数为NULL;根据the documentation1(我的重点)。
Oracle 自动将 expr 和每个搜索值转换为 比较之前的第一个搜索值的数据类型....如果第一个结果具有数据类型 CHAR 或 如果第一个结果为null,则Oracle将返回值转换为数据类型VARCHAR2。
在您的情况下,第一个结果是 NULL,Oracle 将其视为 VARCHAR2。您的返回值被隐式转换为 VARCHAR2。如果您将DECODE()
更改为以下内容,您将获得一个号码:
select decode(1, 0, 0, 0.75)
您可以使用NULLIF()
函数实现您的NULL:
select nullif(decode(1, 0, 0, 0.75), 0) ...
最好使用 CASE 语句,它强制所有返回的数据类型相同:
select case 1 when 0 then null
else 0.75
end ...
1。我也被抓到了。
【讨论】:
【参考方案2】:你可以使用
select decode(1,0,to_number(null),0.75) from dual
【讨论】:
什么?请描述更多!你想说什么? 在解码函数中,如果第一个结果参数是字符串,那么 oracle 会隐式地将其他结果参数转换为字符串。在这种情况下,null 被视为字符串,所以 oracle 将 0.75 转换为字符串并给出 .75 如果你使用 to_number(null) 然后 null 被转换为数字,oracle 给出的结果为 0.75【参考方案3】:在第一种情况下,nvl()
返回一个数值。如何显示取决于您用于运行查询的程序。 TOAD 像你说的那样显示它,0.75。
在第二个示例中,decode()
返回一个varchar2
。当 Oracle 将数字转换为不带任何格式的字符串时,您会得到这样的结果,即“.75”。
来自decode()
上的 Oracle 文档:
如果第一个结果的数据类型为 CHAR 或者如果第一个结果是 null,然后 Oracle 将返回值转换为数据类型 VARCHAR2。
您可以使用数字格式和rtrim()
来实现您的目的,例如:
select rtrim(to_char(.75, '9990.99999999999999'),'0') from dual;
结果:
0.75
【讨论】:
【参考方案4】:select to_number(decode(1,0,null,0.75)) from dual
【讨论】:
以上是关于为啥 Oracle 的 DECODE 给我的价值与 NVL 不同?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL Developer下为啥看不到别人授权给我的表?
为啥 Weka RandomForest 给我的结果与 Scikit RandomForestClassifier 不同?