multiple IS NOT NULL with OR operator - sql

Does anyone know how to improve the below oracle sql query with multiple IS NOT NULL with OR operator:
select count(1)
from s_srv_req sr, s_evt_act act, s_bu bu
where sr.row_id = act.sra_sr_id(+)
and sr.bu_id = bu.row_id
and sr.last_upd > to_date('31-DEC-2013','DD-MON-YYYY')
and **(X_REASON_CODE1 is not null
OR X_REASON_CODE2 is not null
OR X_CONCERN_CODE1 is not null
OR X_CONCERN_CODE2 is not null
OR X_COMPONENT_CODE is not null)**
The purpose here is to fetch all records even if one of the codes column is not null.
Note: This query is taking much time and i cannot progress with such time taking queries. Thanks in advance.

You should use COALESCE function
select count(1)
from s_srv_req sr, s_evt_act act, s_bu bu
where sr.row_id = act.sra_sr_id(+)
and sr.bu_id = bu.row_id
and sr.last_upd > to_date('31-DEC-2013','DD-MON-YYYY')
and COALESCE(X_REASON_CODE1, X_REASON_CODE2, X_CONCERN_CODE1, X_CONCERN_CODE2, X_COMPONENT_CODE) is not null

have you tried with using a excluding method?
Use the total table to minus the records that all of those columns are null at the same time?
here are some fake code:
Method1, using Minus
table a
minus
table a with X_REASON_CODE1 ||
OR X_REASON_CODE2 ||
OR X_CONCERN_CODE1 ||
OR X_CONCERN_CODE2 ||
OR X_COMPONENT_CODE is not null
Method 2, using NOT EXISTS or NOT IN
table a
not exists X_REASON_CODE1 ||
OR X_REASON_CODE2 ||
OR X_CONCERN_CODE1 ||
OR X_CONCERN_CODE2 ||
OR X_COMPONENT_CODE is not null

Related

Observing time difference between Oracle and SQL Server during data migration

We are moving data from Oracle on one Geography to an SQL Server database in another Geography. We are noticing that the time related columns for different objects are different in the two geographies. They are differing by 2 hours.
At source: 2022/05/13 12:01:00
At target: 2022/05/13 10:01:00
I am using this SQL to extract the data at source Oracle database
select distinct item.pitem_id || '~'
|| TO_CHAR(paoItem.PCREATION_DATE, 'dd-Mon-YYYY HH24:MI') || '~'
|| puItemOwner.puser_id || '~'
|| pgItem.pname || '~'
|| puItemLMU.puser_id || '~'
|| TO_CHAR(paoItem.PLAST_MOD_DATE, 'dd-Mon-YYYY HH24:MI')
-- Item Information
from infodba.PITEM item
inner join infodba.PPOM_APPLICATION_OBJECT paoItem on paoItem.puid = item.puid
inner join infodba.PPOM_GROUP pgItem on pgItem.puid = paoItem.ROWNING_GROUPU
inner join infodba.PPOM_USER puItemOwner on puItemOwner.puid = paoItem.ROWNING_USERU
inner join infodba.PPOM_USER puItemLMU on puItemLMU.puid = paoItem.RLAST_MOD_USERU
where item.pitem_id in '3204-001-0613-C';
This query is giving me the correct result itself - 2022/05/13 12:01:00. But when I import this data into the target system, the date is getting update to 2022-05-13 10:01:00.000.
I am assuming that this time difference of 2 hours is because of the probable Geography time difference. If so, what can I do to ensure that the data gets persisted correctly.
Please share me some idea on which options or where to look for this sort of issue.
Thanks,
Pavan.

Cursor in Oracle - after passing parameters, select does not filter result rows

I am facing for me strange issue with following parametrical cursor.
I have defined cursor in this way:
CURSOR cur_action ( product_code VARCHAR2(100) , action_master_list VARCHAR2(100))
IS
SELECT
act.ACTION_DETAIL_KEY,
act.ACTION_MASTER_KEY,
act.PRODUCT_CODE,
act.REF_ACTION_DETAIL_KEY
FROM XMLTABLE(action_master_list) x
JOIN ETDW.MFE_AR_ACTION_DETAILS act ON TO_NUMBER(x.COLUMN_VALUE) = act.ACTION_MASTER_KEY
WHERE 1=1
AND act.LAST_FLAG = 'Y'
AND act.PRODUCT_CODE = product_code;
Then I am using it in following way:
OPEN cur_action ( iFromProductCode , iActionMasterKeyList);
LOOP
FETCH cur_action BULK COLLECT INTO vActionDetailKey, vActionMasterKey, vProductCode, vRefActionDetailKey LIMIT 100;
FOR j IN 1..cur_action%ROWCOUNT
LOOP
dbms_output.put_line('vActionDetailKey: ' || vActionDetailKey (j) ||' vActionMasterKey: '|| vActionMasterKey (j) || ' vProductCode: ' || vProductCode (j));
END LOOP;
END LOOP;
Result seems to be unfilterd. It doesnt return 3 rows as expected result (this result is returned in with cusor query, when i run in outside procedure/pl block), but it returns all rows for actions in list. So it seems, that WHERE condition "act.PRODUCT_CODE = product_code" was not applied. Why?
Thank you
Why? Because you named parameter the same as column, so Oracle reads it as if it was where 1 = 1, i.e. no filtering at all.
Rename parameters to e.g.
CURSOR cur_action ( par_product_code V
----
this
and, later,
AND act.PRODUCT_CODE = par_product_code;
----
this

How to skip column output based on value?

I am using following script to generate objects in C# from Oracle and it works ok.
select 'yield return new Question { QuestionID = '||Q.questionid||', Qcode = "'||Q.Qcode||'", QuestionDescription = "'||Q.questiondescription||'", QuestionText = "'||Q.questiontext||'", QuestionCategoryId = '||Q.questioncategoryid||', QuestionTypeID = '||Q.QuestionTypeID||', IsThunderheadOnly = '|| case q.isthunderheadonly when 0 then 'false' else 'true' end ||', DisplayOrder = '||q.displayorder||' };'
from QUESTION q
where
questioncategoryid = 7
However again and again I run into the problem where I cannot || add columns with NULL values and solution to this point was adding those properties manually, which was ok when selecting up to 20 records.
Now I ran into a case of having to select hundreds of records and adding them manually would take substantial amount of time.
How could I modify the script to add (example) MaxValue property if column in the table is NOT NULL but skip it it if it is?
You can skip it with case ... when ... else like you figured out by yourself:
... ||case when A.NEXTQUESTIONID is not null then 'NextQuestionID = '||A.NEXTQUESTIONID||',' else '' end || ...
You can also use the nvl2 function for a shorter solution:
... || nvl2(A.NEXTQUESTIONID, 'NextQuestionID = '||A.NEXTQUESTIONID||',', '') || ...

firebird trigger string concatenation

anyone can help me with this. I created a trigger in firebird. I have this line that uses concatenation.
NEW.FIELDNAME = FIELD1 || FIELD2;
but it is not working, no record has been inserted. Is there any way for string concatenation? THANKS IN ADVANCE!
here is my full trigger
*query that initiate the variable PREV_STATUS:
SELECT FIRST 1 PREV_STATUSPERMINS FROM C3_EQUIPTSTATEPERMIN
WHERE TESTERID = NEW.TESTERID ORDER BY DATEMODIFIED DESC INTO :PREV_STATUS;
IF(PREV_STATUS IS NULL) THEN
BEGIN
NEW.PREV_STATUSPERMINS = '000';
END
ELSE
BEGIN
NEW.PREV_STATUSPERMINS = PREV_STATUS || NEW.STATUS;
END
You should use the "new" keyword to access the values of your fields within a trigger :
new.fieldname = new.field1 || new.field2;
Also, don't forget that if either of the fields is null, the concatenation will be null. If you want to avoid that, you could do something like this :
NEW.FIELDNAME = coalesce(new.FIELD1, '') || coalesce(new.FIELD2, '')

How to query for a built string select

I would like to do something like
SELECT * FROM (
SELECT ('reword#' || reword) || reword_faq as reword FROM me_review_entries re
) as re
WHERE re.reword = 'reword#2#SOME_FAQ'
I tried to do
SELECT ('reword#' || reword) || reword_faq as foo FROM me_review_entries re
WHERE foo = 'reword#2#SOME_FAQ'
But I get:
ERROR: column "foo" does not exist
LINE 2: WHERE foo = 'reword#2#SOME_FAQ'
Is the first way of doing the only way ? Or could I improve that ?
I think it depends on your database, but the foo column does not exist except within the query, so you might have to do:
SELECT ('reword#' || reword) || reword_faq as foo FROM me_review_entries re
WHERE ('reword#' || reword) || reword_faq = 'reword#2#SOME_FAQ'