Searched Case works / Simple Case doesn't in Oracle - sql

I have the following Searched Case field selection in a Oracle 10g SELECT query
(case
when LOADER_CELLS.CELL_MODE='RW' then 1
when LOADER_CELLS.CELL_MODE='R' then 2
end) as CELL_EDIT_MODE_ID
but if I write it as a Simple Case expression, as follows:
(case LOADER_CELLS.CELL_MODE
when 'RW' then 1
when 'R' then 2
end) as CELL_EDIT_MODE_ID
I get a ORA-12704: character set mismatch error on the when 'RW' line.
I gave a look to the Oracle documentation, and it seems my syntax is correct. http://docs.oracle.com/cd/B19306_01/server.102/b14200/expressions004.htm
Can someone help me on this?

" I supposed that it could be a encoding problem but I don't know how to "cast" the constant strings to a NVARCHAR"
you do it with "N" syntax.
case LOADER_CELLS.CELL_MODE
when n'RW' then 1
when n'R' then 2
end
eg
SQL> select case a when 'a' then 1 end from foo;
select case a when 'a' then 1 end from foo
*
ERROR at line 1:
ORA-12704: character set mismatch
SQL> select case a when n'a' then 1 end from foo;
CASEAWHENN'A'THEN1END
---------------------

Related

decode in oracle convert to postgres

I want to convert the decode function from oracle to postgres command.
example oracle command: select decode(p.statusgeometry,1,'pass','fail') as status
please help & guidance
The decode equivalent is CASE:
WITH p (statusgeometry) AS (VALUES (1),(2))
SELECT
CASE statusgeometry
WHEN 1 THEN 'pass'
WHEN 2 THEN 'fail'
END,
-- The following syntax is useful in case you need to do "something"
-- with the columns depending on the condition, e.g lower(), upper(), etc..
CASE
WHEN statusgeometry = 1 THEN 'pass'
WHEN statusgeometry = 2 THEN 'fail'
END
FROM p;
case | case
------+------
pass | pass
fail | fail
(2 rows)

CASE expression - add one more condition to the WHEN part

I have created a PL/SQL function where I have a case expression in a SQL query. This is working fine, but when I add another when condition it will not compile. Even if I use when ... and 2 > 1, this is also not compiling.
In the below code, the commented part is not working properly.
What I want is to add one more check in my when clause. Please advise.
create or replace function FUNCTION_NAME (date1 in varchar2,value1 in varchar2)
RETURN date
IS
date2 date;
BEGIN
SELECT D DATE2
INTO DATE2 FROM (SELECT CASE (SELECT TO_DATE(MAX(G.DATE3),'DD-MON-YYYY')
FROM TABLE1 G,
TABLE2 N
WHERE G.DATE3=N.DATE3)
WHEN LAST_DAY(TO_DATE(DATE1,'DD-MON-YYYY'))
/* AND MONTHS_BETWEEN (LAST_DAY(TO_DATE(SYSDATE)),
LAST_DAY(TO_DATE(TO_CHAR(DATE1),'DD-MON-YYYY'))) */
THEN LAST_DAY(TO_DATE(DATE1,'DD-MON-YYYY'))
ELSE
TO_DATE('31-DEC-99','DD-MON-YYYY')
END D
FROM DUAL);
RETURN DATE2;
END;
What you have is a case expression (not a case statement).
Case expressions are of two kinds: "simple" (case <expr> when val1 then ... when val2 then... etc.) and "searched" ( case when condition1 then ... when condition2 then ... etc.)
You wrote your case expression as a simple case expression. You can't, then, add conditions to the WHEN part. You must change the case expression to be "searched" all the way through.
case when (select ...) = last_day(...) AND <your commented condition> THEN .....
EDIT - copying part of a clarifying comment below my Answer.
Simple case expression:
case x when 1 then ....
Can also be written as searched case expression:
case when x = 1 then ....
These two are logically equivalent. However, if we want to add "AND 3 > 1" to the WHEN part, that works only in the searched form of the case expression.
There are two flavours of CASE.
Simple CASE:
select case dummy
when 'X' then 1
end as case_demo
from dual;
Searched CASE:
select case
when dummy = 'X' then 1
end as case_demo
from dual;
In your query you are mixing them like this, which won't work:
select case dummy
when 'X' and 1 = 1
then 1
end as case_demo
from dual;
If you switch to a "searched CASE", then you can add more when conditions:
select case
when dummy = 'X' and 1 = 1
then 1
end as case_demo
from dual;

Is there boolean type for column in Oracle SQL?

I tried to:
select 1>2 from dual;
but got:
ORA-00923: FROM keyword not found where expected
Is there boolean type for column expression in Oracle SQL?
I able to do:
select case when 1>2 then 'T' else 'F' end from dual;
Originally I tried to compare date fields and the quickest way I found was getting difference and look to sign...
UPDATE I tried SIGN function, I don't know if it is vendor specific extension:
select SIGN(1-2) from dual;
select SIGN(DATE '2017-01-02' - DATE '2017-02-12') from dual;
but this trick doesn't work for strings...
No there is not, you can use 0 and 1 just as yes/no.
If you need to get the result 1 if something is true and 0 if it is false, you can use a case expression:
select case when (any_logical_condition_here) then 1 else 0 end as my_col
from ....
where ....
For example:
select case when 1 > 2 then 1 else 0 end as bool_result
from dual;
BOOL_RESULT
---------------------------------------
0
NOTE though - "Boolean" refers strictly to the TRUE/FALSE logic, it has no place for UNKNOWN. When you deal with null, as you must in SQL, you need three-valued logic. The case expression as written above returns 1 when the logical condition is true and 0 otherwise. Try it with 1 > null - the truth value is UNKNOWN, the case expression will return 0.

Oracle: How can I get a value 'TRUE' or 'FALSE' comparing two NUMBERS in a query?

I want to compare two numbers. Let's take i.e. 1 and 2.
I've tried to write the following query but it simply doesn't work as expected (Toad says: ORA-00923: FROM keyword not found where expected):
SELECT 1 > 2 from dual
The DECODE is something like a Switch case, so how can I get the result of an expression evalutation (i.e. a number comparison) putting it in the select list?
I have found a solution using a functions instead of an expression in the SELECT LIST: i.e.
select DECODE(SIGN(actual - target)
, -1, 'NO Bonus for you'
, 0,'Just made it'
, 1, 'Congrats, you are a winner')
from some_table
Is there a more elegant way?
Also how do I compare two dates?
There is no boolean types in sql (at least in oracle).
you can use case:
SELECT CASE when 1 > 2 THEN 1 ELSE 0 END FROM dual
But your solution (decode) is also good, read here
The SIGN() function is indeed probably the best way of classifying (in)equality that may be of interest to you if you want to test a > b, a = b and a < b, and it will accept date-date or numeric-numeric as an argument.
I'd use a Case statement by preference, rather than a decode.
Select
case sign(actual-target)
when -1 then ...
when 0 then ...
when 1 then ...
end
SELECT (CASE
WHEN (SIGN(actual - target) > 0 ) THEN
'NO Bonus for you'
ELSE
'Just made it' END)
FROM dual
you can compare two dates with sql
METHOD (1):
SELECT TO_DATE('01/01/2012') - TO_DATE('01/01/2012')
FROM DUAL--gives zero
METHOD (2):
SELECT CASE
when MONTHS_BETWEEN('01/01/2012','01/01/2010') > 0
THEN 'FIRST IS GREATER'
ELSE 'SECOND IS GREATER OR EQUAL' END
FROM dual
sorry i cant format the code the formatting toolbar disappeared !
do any one know why?

Why do I get syntax error Msg 156 when using CASE expression?

I am trying to run this simple query however it doesn't even parse saying
Msg 156, Level 15, State 1, Line 2 Incorrect syntax near the keyword
'between'.
Query is:
select
case DMProject.dbo.TypeFourTraining.Column2
when Column2 between 181 and 360 then '181-360'
when Column2 between 0 and 180 then '0-180'
END as score
from DMProject.dbo.TypeFourTraining
The same doesn't work for Column2 < 360 syntax neither..
I have searched over internet from msdn, and some other sites but I see that my syntax seems to be valid, then either there is a detail I need to know or there is something I can't see :(
Can anyone please suggest a solution?
You cannot mix the simple and searched types of CASE expression. Remove the field name DMProject.dbo.TypeFourTraining.Column2 specified after the CASE.
Correct syntax for your query:
SELECT CASE
WHEN Column2 between 181 AND 360 THEN '181-360'
WHEN Column2 between 0 AND 180 THEN '0-180'
END as score
FROM DMProject.dbo.TypeFourTraining
Two types of CASE expressions:
There are two types of CASE expression namely Simple and Searched. You cannot combine Simple and Searched in the same expression.
Simple CASE:
CASE input
WHEN 1 THEN 'a'
WHEN 2 THEN 'b'
WHEN 3 THEN 'c'
ELSE ''
END
Searched CASE with simple example:
CASE
WHEN input = 1 THEN 'a'
WHEN input = 2 THEN 'b'
WHEN input = 3 THEN 'c'
ELSE ''
END
Searched CASE with slightly complex example:
This involves multiple columns. You can add multiple columns in each of the WHEN statements.
CASEĀ 
WHEN input = 1 AND second_column = 2 THEN 'a'
WHEN input = 2 AND third_column = 3 THEN 'b'
WHEN input = 3 AND (second_column = 4 OR third_column = 6) THEN 'c'
ELSE ''
END
You are mixing up the two forms of the case statement. Try this:
select (case when Column2 between 181 and 360 then '181-360'
when Column2 between 0 and 180 then '0-180'
END) as score
from DMProject.dbo.TypeFourTraining
The other form would be used for singleton values:
select case DMProject.dbo.TypeFourTraining.Column2
when 1 then '1'
when 2 then '2'
etc. etc. etc.
END as score
from DMProject.dbo.TypeFourTraining