Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
441 views
in Technique[技术] by (71.8m points)

java - Why is Oracle's DECODE giving me a different value than NVL?

This query:

select nvl(0.75,0) from dual

gives me 0.75 (numeric) but this query:

select decode(1,0,null,0.75) from dual 

gives me '.75' (string).

Why?

I tried to fix this by changing the second query to:

select decode(1,0,null,to_char(0.75,'0.99')) from dual

but in my actual code the 0.75 will be a field (NUMBER) that may have a different number of decimal places and I'm not suppose to add/remove anything from that value.

Any ideas on how to fix the missing zero issue but still support all possible decimal lengths?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's because the 3rd parameter of your decode statement is NULL; as per the documentation1 (my emphasis).

Oracle automatically converts expr and each search value to the data type of the first search value before comparing.... If the first result has the data type CHAR or if the first result is null, then Oracle converts the return value to the data type VARCHAR2.

In your case the first result is NULL, which Oracle treats as a VARCHAR2. Your return value is being implicitly converted to a VARCHAR2. If you changed your DECODE() to the following you'd get a number:

select decode(1, 0, 0, 0.75)

and you could achieve your NULL by using the NULLIF() function:

select nullif(decode(1, 0, 0, 0.75), 0) ...

It's better to use a CASE statement, which enforces that all returned datatypes are the same:

select case 1 when 0 then null
              else 0.75
       end ...

1. which I've been caught out on as well.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...