4

这个查询:

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),我不打算从该值中添加/删除任何内容。

关于如何解决丢失零问题但仍支持所有可能的十进制长度的任何想法?

4

4 回答 4

6

这是因为您的 decode 语句的第三个参数是 NULL;根据文档1(我的重点)。

Oracle 自动将 expr 和每个搜索值转换为第一个搜索值的数据类型,然后再进行比较...。如果第一个结果的数据类型为 CHAR 或如果第一个结果为空,则 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. 我也被抓到了。

于 2013-09-11T20:04:43.107 回答
3

您可以使用

select decode(1,0,to_number(null),0.75) from dual
于 2014-01-18T11:45:51.417 回答
1

在第一种情况下,nvl()返回一个数值。如何显示取决于您用于运行查询的程序。TOAD像你说的那样显示它,0.75。

在第二个示例中,decode()返回一个varchar2. 当Oracle 将一个数字转换为一个没有任何格式的字符串时,这就是你得到的,即“.75”。

来自 Oracle 文档decode()

如果第一个结果的数据类型为 CHAR 或第一个结果为 null,则 Oracle 将返回值转换为数据类型 VARCHAR2。

您可以使用数字格式rtrim()来实现您的目的,例如:

select rtrim(to_char(.75, '9990.99999999999999'),'0') from dual;

结果:

0.75
于 2013-09-11T20:08:45.880 回答
0
select to_number(decode(1,0,null,0.75)) from dual
于 2018-02-16T10:57:00.000 回答