Error on Oracle Case statement assigning value - sql

I wanted to assign a value "F" to TBL_C.PAY_CODE when its value is T but I cant seem to find the error in this SQL statement. I don't want to use PL/SQL for this just normal SQL statement.
ERROR
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
SQL CODE
SELECT
TBL_A.ACT_ID,
TBL_A.ACT_CODE,
TBL_A.ACT_DESC,
TBL_A.ACT_DIS_DESC,
TBL_B.ACTMAP_ID,
TBL_B.CLI_ID
FROM CACT TBL_A, CMACTM TBL_B, CMACTDM TBL_C
WHERE TBL_A.ACT_ID=TBL_B.ACT_ID AND B.ACTMAP_ID=TBL_C.ACTMAP_ID
AND TBL_C.CODE = 'Version64'
AND TBL_C.ID='100001000000001'
AND TBL_C.PAY_CODE= CASE
WHEN TBL_C.PAY_CODE='T' AND TBL_C.CODE ='Version64'
THEN TBL_C.PAY_CODE='F' <-- ERROR
else TBL_C.PAY_CODE='T'
END;
Update
This query is for retrieving one row which has the following table values. When users submit a button with the following values but with Pay_Code equal to T the row below should be retrieved. I cannot change the value of the pay_code because there are other problems that will be encountered.
Table TBL_C
ACTMAP_ID ID PAY_CODE CODE
100001000000100 100001000000001 F Version64
Original Query Used:
SELECT TBL_A.ACT_ID, TBL_A.ACT_CODE, TBL_A.ACT_DESC, TBL_A.ACT_DIS_DESC, TBL_B.ACTMAP_ID, TBL_B.CLI_ID
FROM CACT TBL_A, CMACTM TBL_B, CMACTDM TBL_C
WHERE TBL_A.ACT_ID=TBL_B.ACT_ID AND B.ACTMAP_ID=TBL_C.ACTMAP_ID
AND TBL_C.CODE =? (Value is Version64)
AND TBL_C.ID=? (Value is 100001000000001)
AND TBL_C.PAY_CODE=? (Either T or F but in the value is set to F)

SELECT TBL_A.ACT_ID, TBL_A.ACT_CODE, TBL_A.ACT_DESC, TBL_A.ACT_DIS_DESC, TBL_B.ACTMAP_ID, TBL_B.CLI_ID
FROM CACT TBL_A, CMACTM TBL_B, CMACTDM TBL_C
WHERE TBL_A.ACT_ID=TBL_B.ACT_ID AND B.ACTMAP_ID=TBL_C.ACTMAP_ID
AND TBL_C.CODE = 'Version64'
AND TBL_C.ID='100001000000001'
AND TBL_C.PAY_CODE= CASE
WHEN TBL_C.PAY_CODE='T' AND TBL_C.CODE ='Version64'
THEN 'F' <-------------
else 'T' <-------------
END;
Note: The fact you are comparing TBL_C.CODE = 'Version64' twice suggests a possible flaw in your logic....

Great question, dimas! I'm not clear on your desired logic, but it appears you want to return records where BL_C.PAY_CODE='T' and TBL_C.CODE ='Version64' or BL_C.PAY_CODE='F'. If this is the case, I would write it:
SELECT
TBL_A.ACT_ID,
TBL_A.ACT_CODE,
TBL_A.ACT_DESC,
TBL_A.ACT_DIS_DESC,
TBL_B.ACTMAP_ID,
TBL_B.CLI_ID
FROM CACT TBL_A, CMACTM TBL_B, CMACTDM TBL_C
WHERE TBL_A.ACT_ID=TBL_B.ACT_ID AND B.ACTMAP_ID=TBL_C.ACTMAP_ID
AND TBL_C.ID='100001000000001'
AND ((TBL_C.PAY_CODE='T' AND TBL_C.CODE ='Version64')
OR TBL_C.PAY_CODE='F');
If I have misread your desired outcome, please clarify and I'll update the answer.

Related

Ambigously defined column in a subquery

I've the following subquery in an sql query:
(
SELECT ID_PLAN, ID_CURSO, NEDICION, NOMBRE AS NOMBREUNIDAD FROM ASISTEN, ALUMNOS, UNIDADES
WHERE ASISTEN.COD = ALUMNOS.COD AND UNIDADES.IDESTRUCTURA = ALUMNOS.IDESTRUCTURA
AND UNIDADES.CDUNDORG = ALUMNOS.CDUNDORG
AND UPPER(TRANSLATE(UNIDADES.NOMBRE, 'áéíóúÁÉÍÓÚ', 'aeiouAEIOU')) LIKE '%CONSEJERIA%'
GROUP BY ID_PLAN, ID_CURSO, NEDICION) ASIS
Problem I have I believe lies in that both table ALUMNOS and UNIDADES have a column named 'NOMBRE' so if I attempt to execute the query I obtain:
00000 - "column ambiguously defined"
To avoid that I thought about changing NOMBRE AS NOMBREUNIDAD to:
UNIDADES.NOMBRE AS NOMBREUNIDAD
But if I do that I get a:
00000 - "not a GROUP BY expression"
So, I don't know what to do so that subquery executes properly.
What should I change to properly execute query without changing the column name?
Aliases are pretty useful, if you use them. The simplify queries and make them easier to read and maintain. I'd suggest you to do so, as it'll also help query to work because Oracle doesn't know which table you actually meant when you selected those 4 columns - which tables do they belong to?
This is just a guess as I don't know your tables so you'll have to fix it yourself. Also, I literally JOINed tables; try to avoid comma-separating them in FROM clause and doing join in WHERE clause as it is supposed to filter data.
GROUP BY, as already commented, is probably useless. If you wanted to fetch distinct set of values, then use appropriate keyword: distinct.
SELECT DISTINCT n.id_plan,
s.id_curso,
u.nedicion,
u.nombre
FROM asisten n
JOIN alumnos s ON n.cod = s.cod
JOIN unidades u
ON u.idestructura = s.idestructura
AND u.cdundorg = s.cdundorg
WHERE UPPER (TRANSLATE (u.nombre, 'áéíóúÁÉÍÓÚ', 'aeiouAEIOU')) LIKE '%CONSEJERIA%'
I managed to solve my problem:
(
SELECT ID_PLAN, ID_CURSO, NEDICION, UNIDADES.NOMBRE AS NOMBREUNIDAD
FROM ASISTEN, ALUMNOS, UNIDADES
WHERE ASISTEN.COD = ALUMNOS.COD AND UNIDADES.IDESTRUCTURA = ALUMNOS.IDESTRUCTURA
AND UNIDADES.CDUNDORG = ALUMNOS.CDUNDORG
AND UPPER(TRANSLATE(UNIDADES.NOMBRE, 'áéíóúÁÉÍÓÚ', 'aeiouAEIOU')) LIKE '%CONSEJERIA%'
GROUP BY UNIDADES.NOMBRE,ID_PLAN, ID_CURSO, NEDICION
)

Using BETWEEN operator in a WHERE clause with dates from an internal table

I have an internal table populated with start and end dates for each type of period. I want to use this internal table in a WHERE clause of an SQL query to select items whose start and end dates are within the open period of their respective type.
TYPES: BEGIN OF s_openprd,
TETXT TYPE TETXT,
fromdate TYPE d,
todate TYPE d,
END OF s_openprd.
DATA: it_openprd TYPE TABLE OF s_openprd WITH KEY TETXT.
SELECT * FROM FPLT
INNER JOIN #it_openprd AS OP ON FPLT~TETXT = OP~TETXT
WHERE FPLT~FKDAT BETWEEN OP~fromdate AND OP~todate
AND FPLT~NFDAT BETWEEN OP~fromdate AND OP~todate
However I get the error saying that OP~fromdate should be of a compatible type to be used as an operator with BETWEEN. The types listed include the date type d.
I've tried replacing BETWEEN with regular >= and <= operators:
SELECT * FROM FPLT
INNER JOIN #it_openprd AS OP ON FPLT~TETXT = OP~TETXT
WHERE FPLT~FKDAT >= OP~fromdate AND FPLT~FKDAT <= OP~todate
AND FPLT~NFDAT >= OP~fromdate AND FPLT~NFDAT <= OP~todate
But the query returns incorrect results.
I assume the ABAP type d is incompatible with SQL type d ?
How can I use an internal table to restrict the selection in this way ?
Nothing prevents you from using FOR ALL ENTRIES instead of joining with internal table, if you ABAP version does not support it.
Regarding "incorrect results" I agree with Sandra, BETWEEN and LT/GT have totally identical sense, so it is more a matter of what you expect than correctness. I'd rather utilize standard logic for dealing with the issue that bothers you:
The problem with FPLT-NFDAT and FPLT-FKDAT is that their order is not consistent. In one entry, the value of NFDAT may be anterior to FKDAT and in another entry it's the opposite.
Following the same approach for you SQL query, you can write something like this:
TYPES: BEGIN OF ty_fplt,
fplnr TYPE fplnr,
fkdat TYPE fkdat,
nfdat TYPE nfdat,
END OF ty_fplt,
tt_fplt TYPE STANDARD TABLE OF ty_fplt WITH NON-UNIQUE KEY fkdat nfdat.
DATA(lt_fplt_base) = VALUE tt_fplt( ).
SELECT fplnr, CASE WHEN nfdat < fkdat THEN nfdat ELSE fkdat END AS fkdat,
CASE WHEN nfdat < fkdat THEN fkdat ELSE nfdat END AS nfdat
FROM fplt
INTO TABLE #lt_fplt_base.
SELECT *
FROM fplt AS f
INTO TABLE #DATA(result)
FOR ALL ENTRIES IN #lt_fplt_base
WHERE f~fplnr = #lt_fplt_base-fplnr
AND f~fkdat >= #lt_fplt_base-fkdat
AND f~nfdat <= #lt_fplt_base-nfdat.
Don't take it as a rule of thumb, it is just a quick suggestion.
P.S. Joining by text field INNER JOIN #it_openprd AS OP ON FPLT~TETXT = OP~TETXT does not make sense in any context. Text/string fields are often ambiguous, they often contain control characters, whitespaces, etc., which make them useless for primary key.

Oracle database error 907: ORA-00907: missing right parenthesis

I transferred this code directly from SQL developer. Works perfectly in there.
SELECT
a.INCIDENT_NUMBER,
a.DETAILED_DESCRIPTION,
a.INCIDENT_ROOT_CAUSE
FROM
N_EVALUATION as a
INNER JOIN N_DISPOSITION as b
ON (a.INCIDENT_NUMBER = b.INCIDENT_NUMBER)
WHERE
b.DISPOSITION_LINE_NUM in (NULL, 1) AND
a.ACTIVE_FLAG = 'Y' AND
b.ACTIVE_FLAG = 'Y' AND
a.DETAILED_DESCRIPTION IS NOT NULL
However when I transfer the same exact code into Tableau to create a custom SQL query. It gives me an error;
An error occurred while communicating with the data source. Bad
Connection: Tableau could not connect to the data source. Oracle
database error 907: ORA-00907: missing right parenthesis
This has me completely stumped, not really sure what to do here. Any help or advice is much appreciated. I am more concerned regarding the missing right parenthesis rather than the bad connection.
Remove the AS from the FROM clause. Oracle does not recognize that.
In addition, this condition:
b.DISPOSITION_LINE_NUM in (NULL, 1)
Does not do what you expect. It never evaluates to true if b.DISPOSITION_LINE_NUM is NULL.
You should replace it with:
(b.DISPOSITION_LINE_NUM IS NULL OR b.DISPOSITION_LINE_NUM = 1)
Otherwise, your query looks like it has balanced parentheses, but you should write it as:
SELECT e.INCIDENT_NUMBER, e.DETAILED_DESCRIPTION, e.INCIDENT_ROOT_CAUSE
FROM N_EVALUATION e JOIN
N_DISPOSITION d
ON e.INCIDENT_NUMBER = d.INCIDENT_NUMBER
WHERE (d.DISPOSITION_LINE_NUM IS NULL OR d.DISPOSITION_LINE_NUM = 1) AND
e.ACTIVE_FLAG = 'Y' AND
d.ACTIVE_FLAG = 'Y' AND
e.DETAILED_DESCRIPTION IS NOT NULL;
Notes:
User meaningful table aliases rather than arbitrary letters (this uses abbreviations).
Do not use as in the FROM clause.
Be careful with NULL comparisons.
Finally, your original query is equivalent to:
SELECT e.INCIDENT_NUMBER, e.DETAILED_DESCRIPTION, e.INCIDENT_ROOT_CAUSE
FROM N_EVALUATION e JOIN
N_DISPOSITION d
ON e.INCIDENT_NUMBER = d.INCIDENT_NUMBER
WHERE d.DISPOSITION_LINE_NUM = 1 AND
e.ACTIVE_FLAG = 'Y' AND
d.ACTIVE_FLAG = 'Y' AND
e.DETAILED_DESCRIPTION IS NOT NULL;
This has no parentheses. So it cannot return that particular error.

How to use CASE expression to update a table with inner queries

I have used the following update query :
UPDATE datA_table T
SET T.VALUE=
(SELECT
CASE
WHEN t3.h1 =(t3.h2) and t3.h1=(t3.h3) THEN t3.h1
ELSE
Case
wHEN T3.h1 < > T3.h2 THEN T3.h2
ELSE
cASE
wHEN T3.h1 < > T3.h3 THEN T3.h3
eND
eND
END
from datA_table t3)T1
where t.time=t1.time and t.name=t1.name
But this is giving the following error:
Error report - SQL Error: ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
Is there any way to resolve this issue?
You can have many WHEN in each CASE, which is also likely to perform better than nested CASEs. I'm unfamiliar with the way you linked the updated table with the subselect (normally you can't refer to internal aliases in a subquery from outside), and don't know if it works at all, so I coded it in a way I know for sure it works:
UPDATE datA_table T
SET T.VALUE=
(SELECT
CASE
WHEN t3.h1 =(t3.h2) and t3.h1=(t3.h3) THEN t3.h1
WHEN T3.h1 < > T3.h2 THEN T3.h2
wHEN T3.h1 < > T3.h3 THEN T3.h3
END
from datA_table t3
where t.id=t3.id AND T.name=T3.name
)
where <your condition for datA_table rows to be updated>
Update
I just noticed that both the table being modified and the table in the subquery are the same table, and that the joining condition is likely to be a key. Therefore, there is no need to specify a subquery at all. The following simpler UPDATE will do the same, but likely much faster (I also improved the CASE logic, as the first test was superfluous):
UPDATE datA_table
SET VALUE = CASE
WHEN h1 <> h2 THEN h2
WHEN h1 <> h3 THEN h3
ELSE h1
END
WHERE <your condition for rows to be updated>
The syntax is incorrect. Everything after the parenthesis ending the SELECT should be omitted.
The subselect takes the place of <expression> in
UPDATE data_table SET value = <expression>
By the way, The CASE construction is overly complicated; you could use a single CASE expression like in
CASE WHEN <condition1>
THEN <expression1>
WHEN <condition2>
THEN <expression2>
...
ELSE <expression>
END

getting error that Error:SQL problems: Inconsistent datatypes: expected NUMBER got CHAR

I wrote a query. The problem is if i remove the case statement then error disappear but if i use the case statement then error comes and case statement is necessary. Here is the query
Select
b.branch_name AS "BRANCHES", --varchar2(100 byte)
(
Select count(temp.loan_acct_no) --varchar2(30 byte)
From
(
Select *
From
Losa_app app
inner join
losa_cust lc
on
(lc.app_ref_no = app.app_ref_no ) --varchar2(20 byte)
and
lc.app_joint_T= 'P' --varchar2(10 byte)
inner join
losa_facilities lf
on
(lf.app_ref_no = app.app_ref_no) --varchar2(20 byte)
)
temp
where
temp.attend_branch = b.branch_id --NUMBER(10, 0)
) AS "No.of Account"
From
code_branch b
where
b.branch_code1 --varchar2(16 byte)
like
case :inputChannel
when 'AIBB' Then '0347%' --AIBB or ABB (varchar2(10 byte))
When 'ABB' Then '0232%'
end
In this case error comes but if i remove the lines
where
b.branch_code1
like
case :inputChannel
when 'AIBB' Then '0347%'
When 'ABB' Then '0232%'
end
Then error gone. I think error is coming because my case statement is returning char data. How can i convert my case statement to return number instead of char ?
Thanks
done. I request to administrator that move this question to iReport section. Because the query is right but i did something wrong while put this query in the iReport. Actually in oracle when we want input then we write like :inputChannel. For same thing in iReport we define parameters like $P{inputChannel}. So what i did wrong is that when i defined the parameter $P{inputChannel}, then i didn't set its Default value expression which should be "". AFter doing this error gone in iReport.
I don't know how to move it to iReport section otherwise i do it by myself. Sorry but i thought may be i am doing something wrong with the query, sorry :(