not in condition not working with Case statement PLSQL - oracle

NOT IN condition, it is not working. I have these records in the table
proj_comp_id
proj_no
1050-WE-0005
8661
TOGG0000001
1581
5207-00GAC01AA502
8662
so it should add an error for the 2nd value..but not working pls help. below code is adding errors for 1 and 3rd lines also.
SELECT p.proj_comp_no AS primarykey,
p.proj_comp_id AS proj_comp_id,
pr.proj_id AS proj_id,
p.proj_no,
CASE
WHEN p.proj_comp_id NOT IN ('5207-%',
'1051-%',
'1050-%',
'1048-%',
'1049-%',
'2006-%',
'5203-%',
'1055-%',
'1056-%',
'1054-%') and p.proj_no NOT like (1581)
THEN
'1TAG_ID does not start with project prefix, pls add project prefix(5207-, 1049-,1048)'
ELSE
'NO ERROR'
END AS tag_ID_ERROR,
p.descr AS descr
FROM proj_comp p
LEFT JOIN std_mat_cls l
ON l.std_mat_cls_no = p.std_mat_cls_no
LEFT JOIN std_mat b
ON p.proj_comp_id = b.std_mat_id
LEFT JOIN proj pr
ON p.proj_no = pr.proj_no
WHERE (SELECT m.mat_stat_ext_id
FROM mat_stat_ext m
WHERE p.mat_stat_ext_no = m.mat_stat_ext_no) IN ('N', 'P')
AND b.std_mat_id IS NULL
***

That must be because IN isn't appropriate in this context. You should switch to something else, e.g. separate LIKE conditions:
No:
WHEN p.proj_comp_id NOT IN ( '5207-%', '1051-%', '1050-%', etc.
Yes:
WHEN p.proj_comp_id NOT LIKE '5207-%'
AND p.proj_comp_id NOT LIKE '1051-%'
AND p.proj_comp_id NOT LIKE '1050-%'
etc.

The other way to test this could be solved using the InStr() function...
WHEN
InStr('5207-, 1051-. 1050-, 1048-, 1049-, 2006-, 5203-, 1055-, 1056-, 1054-', SubStr(p.proj_comp_id, 1, 5)) = 0

Related

How to use case expression or should go for any other option

I have a table that looks something like this, Report_Table:
Report_DEFINITION_NAME
Report_CORE_NAME
COMPLETION_STATUS
COMPLETION_DATE
ReportAD
AD
Success
14-01-2019
ReportBB
BB
Error
24-06-2022
ReportAD
AD
Error
19-03-2020
ReportR5
R5
Success
04-06-2022
ReportG8
G8
Error
04-06-2022
ReportR5
R5
Success
18-11-2020
ReportLH
LH
Success
07-09-2019
ReportU6
U6
Error
12-05-2022
ReportAD
AD
Success
23-09-2021
I wanted to pull data from Report_table. If COMPLETION_STATUS is Success it should give the latest Success COMPLETION_DATE table date and if it has Error it should give the last Success COMPLETION_DATE table date as well as the Error date. Something like
select Report_DEFINITION_NAME, Report_Core_name, COMPLETION_STATUS, COMPLETION_DATE,
CASE:
WHEN COMPLETION_STATUS='Success' THEN latest Success COMPLETION_DATE
WHEN COMPLETION_STATUS='Error' THEN last Success COMPLETION_DATE
WHEN COMPLETION_STATUS='Error' THEN latest Error COMPLETION_DATE
END
from Report_Table;
the output should be in a single query identified by core name or definition name.
So, I have used IN clause to solve my problem and no Case expression.
Getting the max value in a select statement and calling that statement using IN clause from my parent select statement solved my problem.
something like:
SELECT
a.*,
a.completion_date,
b.completion_date AS last_success_date
FROM report_table a, report_table b
WHERE a.report_definition_name = b.report_definition_name
AND a.completion_date IN
(
SELECT MAX(su.completion_date)
FROM report_table su
WHERE su.completion_status = 'Success'
AND b.report_definition_name = su.report_definition_name
)
ORDER BY a.completion_date DESC;

SQLRPGLE & JSON_OBJECT CTE Statements -101 Error

This program compiles correctly, we are on V7R3 - but when running it receives an SQLCOD of -101 and an SQLSTATE code is 54011 which states: Too many columns were specified for a table, view, or table function. This is a very small JSON that is being created so I do not think that is the issue.
The RPGLE code:
dcl-s OutFile sqltype(dbclob_file);
xfil_tofile = '/ServiceID-REFCODJ.json';
Clear OutFile;
OutFile_Name = %TrimR(XFil_ToFile);
OutFile_NL = %Len(%TrimR(OutFile_Name));
OutFile_FO = IFSFileCreate;
OutFile_FO = IFSFileOverWrite;
exec sql
With elm (erpRef) as (select json_object
('ServiceID' VALUE trim(s.ServiceID),
'ERPReferenceID' VALUE trim(i.RefCod) )
FROM PADIMH I
INNER JOIN PADGUIDS G ON G.REFCOD = I.REFCOD
INNER JOIN PADSERV S ON S.GUID = G.GUID
WHERE G.XMLTYPE = 'Service')
, arr (arrDta) as (values json_array (
select erpRef from elm format json))
, erpReferences (refs) as ( select json_object ('erpReferences' :
arrDta Format json) from arr)
, headerData (hdrData) as (select json_object(
'InstanceName' : trim(Cntry) )
from padxmlhdr
where cntry = 'US')
VALUES (
select json_object('header' : hdrData format json,
'erpReferenceData' value refs format json)
from headerData, erpReferences )
INTO :OutFile;
Any help with this would be very much appreciated, this is our first attempt at creating JSON for sending and have not experienced this issue before.
Thanks,
John
I am sorry for the delay in getting back to this issue. It has been corrected, the issue was with the "values" statement.
This is the correct code needed to make it work correctly:
Select json_object('header' : hdrData format json,
'erpReferenceData' value refs format json)
INTO :OutFile
From headerData, erpReferences )

Getting Repository dependencies

I'm using Informatica with Oracle RDBMS. Lately I've been struggling a bit.
I got an assignment to query the dependencies between each Model/Workflow , so the desired result will look something like this:
GRAND_MODEL | GRAND_WORKFLOW | WAIT_4_MODEL | WAIT_4_WORKFLOW
DWH_Model1 WF_workflow1 DWH_Model3 WF_Workflow3_1
DWH_Model1 WF_workflow1 DWH_Model4 WF_Workflow4_1
DWH_Model2 WF_workflow2_1 DWH_Model1 WF_Workflow1
Which means, WF_workflow1 in model DWH_Model1 waits for workflow WF_Workflow3_1 in model DWH_Model3 ETC....
We have 3 types of workflows , DELTA (will contains the word DELTA) DWH (same here) and CALC(same here). A workflow that waits uses an EVENT that will contain both of the models names, and a workflow that flags contain a CMD that contain the grand_model name.
So far We've come up with this:
SELECT DISTINCT OA.SUBJ_NAME AS GRAND_MODEL,
OL.SUBJ_NAME AS WAIT_4_MODEL_NAME,
REP.WORKFLOW_NAME AS WAIT_4_WORKFLOW_NAME,
A.FLAG_NAME,
CASE
WHEN INSTR(UPPER(A.FLAG_NAME), 'DWH') > 0 THEN
'DWH'
WHEN INSTR(UPPER(REP.WORKFLOW_NAME), 'DELTA') > 0 THEN
'DELTA'
ELSE
'CALC'
END CONNECTION_NAME
FROM OPB_SUBJECT#TO_INFORMATICA_ADMIN OL,
OPB_SUBJECT#TO_INFORMATICA_ADMIN OA,
OPB_TASK#TO_INFORMATICA_ADMIN T,
OPB_TASK#TO_INFORMATICA_ADMIN TL,
OPB_TASK_INST#TO_INFORMATICA_ADMIN TI,
REP_SESSION_INSTANCES#TO_INFORMATICA_ADMIN REP,
(SELECT T.TASK_ID,
SUBSTR(T.ATTR_VALUE,
LENGTH(T.ATTR_VALUE) + 2 -
INSTR(REVERSE(T.ATTR_VALUE), '/')) FLAG_NAME
FROM OPB_TASK_ATTR#TO_INFORMATICA_ADMIN T
WHERE T.TASK_TYPE = 60
AND INSTR(REVERSE(T.ATTR_VALUE), '/') > 0) A,
(SELECT T.TASK_ID,
T.SUBJECT_ID,
SUBSTR(T.PM_VALUE,
LENGTH(T.PM_VALUE) + 2 -
INSTR(REVERSE(T.PM_VALUE), '/')) FLAG_NAME
FROM OPB_TASK_VAL_LIST#TO_INFORMATICA_ADMIN T
WHERE INSTR(REVERSE(T.PM_VALUE), '/') > 0) L
WHERE OL.SUBJ_ID = L.SUBJECT_ID
AND A.TASK_ID = T.TASK_ID
AND T.SUBJECT_ID = OA.SUBJ_ID
AND A.FLAG_NAME = L.FLAG_NAME
AND OL.SUBJ_NAME <> OA.SUBJ_NAME
AND L.TASK_ID = TL.TASK_ID
AND TL.TASK_ID = TI.TASK_ID
AND TI.WORKFLOW_ID = REP.WORKFLOW_ID
This query works! The problem is, I'm getting worklets as workflows as well, so some of the times the last joins fails. I don't know how to avoid it..

1 result set from 3 queries?

I'm at my wits end attempting to make this happen. Currently I have 3 separate queries. For automation purposes I need to get the results of these three queries in one output, I cannot seem to join them properly to get the expected results.
QUERY 1:
SELECT OH.EXTN_HOST_ORDER_REF,
OL.EXTN_HOST_ORDER_LINE_REF,
OL.ORIGINAL_ORDERED_QTY,
OL.EXTN_TENDER_QUANTITY,
OL.EXTN_CUM_PICK_QTY,
OL.SHIPPED_QUANTITY,
OL.EXTN_REFUND_QTY
FROM YFS_ORDER_HEADER OH,
YFS_ORDER_LINE OL
WHERE OH.ORDER_HEADER_KEY = OL.ORDER_HEADER_KEY
AND OH.DOCUMENT_TYPE = '0001'
AND OH.EXTN_HOST_ORDER_REF = 'xxxxxxxxxxx'
ORDER BY PL.EXTN_HOST_ORDER_LINE_REF ASC;
QUERY 2:
SELECT RS.STATUS_QUANTITY AS RETURNED_QTY
FROM YFS_ORDER_HEADER OH,
YFS_ORDER_LINE OL,
YFS_ORDER_RELEASE_STATUS RS
WHERE OH.ORDER_HEADER_KEY = OL.ORDER_HEADER_KEY
AND OL.ORDER_LINE_KEY = RS.ORDER_LINE_KEY
AND RS.STATUS = '3700.02'
AND OH.EXTN_HOST_ORDER_REF = 'xxxxxxxxxxx';
QUERY 3
SELECT RS.STATUS_QUANTITY AS CANCELLED_QTY
FROM YFS_ORDER_HEADER OH,
YFS_ORDER_LINE OL,
YFS_ORDER_RELEASE_STATUS RS
WHERE OH.ORDER_HEADER_KEY = OL.ORDER_HEADER_KEY
AND OL.ORDER_LINE_KEY = RS.ORDER_LINE_KEY
AND RS.STATUS = '9000'
AND OH.EXTN_HOST_ORDER_REF = 'xxxxxxxxxxx';
The query should show NULL values where no data exists from query 2 & 3.
Thanks in advance for your help and advice!
If you are allowed to show both returned and cancelled quantities, the following simple edit should work. Hope this helps.
SELECT oh.extn_host_order_ref,
ol.extn_host_order_line_ref,
ol.original_ordered_qty,
ol.extn_tender_quantity,
ol.extn_cum_pick_qty,
ol.shipped_quantity,
ol.extn_refund_qty,
DECODE (rs.status, '3700.02', rs.status_quantity) AS returned_qty,
DECODE (rs.status, '9000', rs.status_quantity) AS cancelled_qty
FROM yfs_order_header oh
INNER JOIN yfs_order_line ol
ON oh.order_header_key = ol.order_header_key
LEFT OUTER JOIN yfs_order_release_status rs
ON ol.order_line_key = rs.order_line_key
WHERE oh.document_type = '0001' AND oh.extn_host_order_ref = 'xxxxxxxxxxx'
ORDER BY pl.extn_host_order_line_ref ASC;

Problem in oracle query

Hai guys,
I've a query in which i need to interchange the values of two fields.
The query is as follows:
SELECT TO_DATE(A.G_LEDGER_DATE,'dd/mm/YYY')as G_LEDGER_DATE,C.ACC_MASTER_NAME,
A.G_LEDGER_REF_NO ,
NVL(CASE WHEN B.G_LEDGER_SECTION = 1 THEN
CASE WHEN
(SELECT COUNT(*)FROM SOSTRANS.ACC_GEN_LEDGER WHERE G_LEDGER_SECTION = B.G_LEDGER_SECTION AND G_LEDGER_ID = B.G_LEDGER_ID)> 1 THEN
B.G_LEDGER_VALUE ELSE A.G_LEDGER_VALUE END END,0) AS G_LEDGER_DR_VALUE,
NVL(CASE WHEN B.G_LEDGER_SECTION = -1 THEN
CASE WHEN
(SELECT COUNT(*) FROM SOSTRANS.ACC_GEN_LEDGER WHERE G_LEDGER_SECTION = B.G_LEDGER_SECTION AND G_LEDGER_ID = B.G_LEDGER_ID)> 1 THEN
B.G_LEDGER_VALUE ELSE A.G_LEDGER_VALUE END END,0) AS G_LEDGER_CR_VALUE,
B.G_LEDGER_SECTION,C.ACC_MASTER_ID,SUBSTR(A.G_LEDGER_REF_NO,0,3) AS Types,'Z' as OrderChar ,
CASE WHEN A.G_LEDGER_REMARK IS NULL THEN B.G_LEDGER_REMARK ELSE A.G_LEDGER_REMARK END AS Narration
FROM SOSTRANS.ACC_GEN_LEDGER A
LEFT OUTER JOIN SOSTRANS.ACC_GEN_LEDGER B ON A.G_LEDGER_ID = B.G_LEDGER_ID
LEFT OUTER JOIN SOSMASTER.ACC_ACCOUNT_MASTER C ON A.ACC_MASTER_ID = C.ACC_MASTER_ID WHERE A.G_LEDGER_CANCEL='N' AND
B.ACC_MASTER_ID = 'MSOS000001' AND
A.ACC_MASTER_ID <> 'MSOS000001' AND
A.G_LEDGER_SECTION <> B.G_LEDGER_SECTION AND
A.G_LEDGER_DATE >= '25/sep/2009' AND
A.G_LEDGER_DATE<='26/sep/2009'
ORDER BY OrderChar,G_LEDGER_DATE
Now i get the output as
... G_LEDGER_DR_VALUE G_LEDGER_CR_VALUE .....
... 2000 0 .....
... 3000 0 .....
... -1000 0 .....
I need to get the negetive value of the G_LEDGER_DR_VALUE side in G_LEDGER_CR_VALUE and if negetive value exists in G_LEDGER_CR_VALUE then it should be in the G_LEDGER_DR_VALUE field
Can anyone help me to solve this?
If I understood your question well, you select a value (that I will call g_ledger_value) that you want to appear in a different column depending on its sign.
This is how I would do it :
SELECT
CASE WHEN t.g_ledger_value>0 THEN t.g_ledger_value ELSE 0 END AS g_ledger_dr_value,
CASE WHEN t.g_ledger_value<0 THEN t.g_ledger_value ELSE 0 END AS g_ledger_cr_value
FROM
(SELECT g_ledger_value FROM mytable) t;
It sounds like a combination of SIGN() and CASE is what you need ...
CASE WHEN SIGN(G_LEDGER_DR_VALUE) = -1 then ...
ELSE ...
END
etc
SELECT G_LEDGER_DR_VALUE,
CASE WHEN G_LEDGER_DR_VALUE < 0
THEN G_LEDGER_CR_VALUE
ELSE G_LEDGER_DR_VALUE
END
FROM (...)
Is it that you mean? I suggest calculate values of CR___VALUE and DR_VALUE in subquery, and then in wrapping query make CASE which returns you correct value.

Resources