Search code examples
oracle-databaseoracle11gcaseoracle11gr2nvl

CASE Statement and NVL provides different output in Oracle11G


I have a string having only digits and a space.
I am using CASE and NVL function to get the output.
If string is NULL then use the same string value else use 1.
I am able to different behavior for SQL and PLSQL.
Can anyone provide some explanation about this behavior and which one is the best approach to follow.

in SQL

NVL function works and provides result without TRIM

WITH T AS (SELECT ' 1234' LV FROM DUAL )
SELECT '"'||NVL(LV,1)||'"'  LV
FROM T;

LV    
-------
" 1234" 

CASE gives ORA-00932 error

WITH T AS (SELECT ' 1234' LV FROM DUAL )
SELECT CASE WHEN LV IS NOT NULL THEN LV ELSE 1 END
FROM T;


Error report:
SQL Error: ORA-00932: inconsistent datatypes: expected CHAR got NUMBER
00932. 00000 -  "inconsistent datatypes: expected %s got %s"
*Cause:    
*Action:

in PLSQL

NVL provides result with space

SET SERVEROUTPUT ON
DECLARE
LV VARCHAR2(10):=' 1234';
BEGIN
DBMS_OUTPUT.PUT_LINE('BEFORE CASE -"'||LV||'"');
LV:=NVL(LV,1);
DBMS_OUTPUT.PUT_LINE('AFTER CASE -"'||LV||'"');
END;

Result:
BEFORE CASE -" 1234"
AFTER CASE -" 1234"

Case Statement TRIMs the result

SET SERVEROUTPUT ON
DECLARE
LV VARCHAR2(10):=' 1234';
BEGIN
DBMS_OUTPUT.PUT_LINE('BEFORE CASE -"'||LV||'"');
LV:=CASE WHEN LV IS NOT NULL THEN LV ELSE 1 END;
DBMS_OUTPUT.PUT_LINE('AFTER CASE -"'||LV||'"');
END;

Result:
BEFORE CASE -" 1234"
AFTER CASE -"1234"

Solution

  • Problem is in your case statement.

    CASE WHEN LV IS NOT NULL THEN LV ELSE 1 END

    Here LV is of type varchar and in else statement, You are assigning 1 as an integer value which created problem for different data types.

    Just update your case statement as mentioned below and it will work in oracle

    CASE WHEN LV IS NOT NULL THEN LV ELSE '1' END