I want to tune below query eliminating NOT EXIST clause specified in it. Can you please help.
GLT_temp_upload is temporary table where as DA_DUEDATE is partitioned table having huge data in it.
Please help
SELECT DISTINCT
batchid,
store_area,
STORE_AREA
|| ','
|| STORE_ID
|| ','
|| SMS_ID
|| ','
|| SMS_SERVICE
|| ','
|| SYNERGY_MODE_ID
|| ','
|| FREQUENCY
|| ','
|| DUEDATE
|| ','
|| STUDY_ID
|| ','
|| YEAR
|| ''
|| WEEK_ID
||',Not exist in Da_Duedate'
FROM GLT_temp_upload upload
WHERE upload.batchid = 1
AND NOT EXISTS
(SELECT due.week_id,
due.country_id,
due.year,
due.study_id,
due.store_id,
due.store_area,
due.synergy_mode_id,
upload.batchid,
due.due_date,
upload.sms_service
FROM DA_DUEDATE due
WHERE due.store_id = upload.store_id
AND due.study_id = upload.study_id
AND due.store_area = upload.store_area
AND due.frequency = upload.frequency
AND due.sms_service = upload.sms_service
AND due.week_id = upload.week_id
AND due.country_id = upload.country_id
AND due.year = upload.year
AND due.sms_id = upload.sms_id
AND due.synergy_mode_id =
upload.synergy_mode_id)
You may try NOT EXISTS / LEFT JOIN / NOT IN
In your NOT EXISTS it's enough to SELECT 1 instead of the list of columns
Sometimes LEFT JOIN can be more beneficial (depending on indexes, the size of the tables etc)
SELECT DISTINCT
batchid,
store_area,
STORE_AREA
|| ','
|| STORE_ID
|| ','
|| SMS_ID
|| ','
|| SMS_SERVICE
|| ','
|| SYNERGY_MODE_ID
|| ','
|| FREQUENCY
|| ','
|| DUEDATE
|| ','
|| STUDY_ID
|| ','
|| YEAR
|| ''
|| WEEK_ID
||',Not exist in Da_Duedate'
FROM GLT_temp_upload upload left join DA_DUEDATE due
ON due.store_id = upload.store_id
AND due.study_id = upload.study_id
AND due.store_area = upload.store_area
AND due.frequency = upload.frequency
AND due.sms_service = upload.sms_service
AND due.week_id = upload.week_id
AND due.country_id = upload.country_id
AND due.year = upload.year
AND due.sms_id = upload.sms_id
AND due.synergy_mode_id = upload.synergy_mode_id
WHERE upload.batchid = 1 and due.store_id is NULL;
I'd recommend you looking at the execution plan to find an optimal solution for your case.
Related
I'm trying to print qrcode using esc/pos commands.
Text I want to print is 'ABCD'
Printer is Bixolon srp E300
According to command manual , my code looks like this:
init := chr(27) || chr(64);
center := chr(27) || 'a1';
fn165 := chr(29) || '(k' || chr(4) || chr (0) || chr(49) || chr(65) || chr(50) || chr(0) ;
fn167 := chr(29) ||'(k30' || chr(49) || chr(67) || chr(5);
fn180 := chr(29) || '(k' || chr(7) || chr(0) || chr(49) || chr(80) || chr(48) || chr(65) || chr(66) || chr(67) || chr(68);
fn181 := chr(29) || '(k30' || chr(49) || chr(81) || chr(48) ;
all := fn165 || fn167 || fn180 || fn181;
call print (init);
call print (center);
call print (all);
And my print output looks like in the picture..
But when I try to scan qr code, I get an empty string ( no text).
I suppose that something is wrong with my fn180 line so I tried to modify it:
fn180 := chr(29) || '(k' || '07' || '00' || chr(49) || chr(80) || chr(48) || chr(65) || chr(66) || chr(67) || chr(68);
But I still got the same output.
When I changed fn180 to
fn180 := chr(29) || '(k' || '7' || '0' || chr(49) || chr(80) || chr(48) || chr(65) || chr(66) || chr(67) || chr(68);
my printer freezes..
What I'm doing wrong?
The following stored procedure works fine when I use static sql to insert values into the DBCMNGR.ALERTREQUEST but does not work when trying to use the dynamic sql string.
I get invalid date literal and time literal when trying to call the below stored procedure.
CALL TESTDB.ALERT_REQUEST_INSERT('Test_JobName','Test_JobDescription',
'Test_ActionDestination','Test_JobFullMessage')
Need help to actually work this without any errors.
In the DBCMNGR.ALERTREQUEST the DATE and time are defined as follows:
ReqDate DATE FORMAT 'YYYY/MM/DD'
ReqTime INTEGER
REPLACE PROCEDURE TESTDB.ALERT_REQUEST_INSERT( IN p_JobName CHARACTER(60), IN p_JobDescription CHARACTER(120), IN p_ActionDestination CHARACTER(120), IN p_JobFullMessage CHARACTER(600) ) )
BEGIN
SET SQLSTR = 'INSERT INTO DBCMNGR.ALERTREQUEST ' || '(AlertRequest.ReqDate ' || ',AlertRequest.ReqTime ' || ',AlertRequest.JobName ' || ',AlertRequest.Description ' || ',AlertRequest.EventValue ' || ',AlertRequest.ActionCode ' || ',AlertRequest.RepeatPeriod ' || ',AlertRequest.Destination ' || ',AlertRequest.Message ' || ') ' || 'VALUES ( ' || ' DATE ' || ',TIME ' || ''',''' || TRIM(p_JobName) || ''',''' || TRIM(p_JobDescription) || ''',0 ' || ',''+'' ' || ',0 ' || ''',''' || TRIM(p_ActionDestination) || ',''' || TRIM(p_JobFullMessage) || ''');';
EXECUTE IMMEDIATE SQLSTR; END;
I can't seem to use a VARCHAR2 of more than 4000 chars in 11G, but I see that I should be able to get to 32776.
PROCEDURE prcName
(piCoSite IN CHAR
,piRaciId IN NUMBER
,piDept IN VARCHAR2
,poRecordset OUT SYS_REFCURSOR) AS
locSql1 VARCHAR2(32000 CHAR);
BEGIN
locSql1 :=
'SELECT' ||
' H.TABLE_HEAD_ID ' ||
' ,H.TABLE_HEAD_DEPT ' ||
' ,H.TABLE_HEAD_DESCRIPTION ' ||
' ,H.TABLE_HEAD_STATUS ' ||
' ,H.TABLE_HEAD_SCOPE ' ||
' ,H.TABLE_HEAD_ORIGINATOR ' ||
' ,H.TABLE_HEAD_SUB_CATEGORY ' ||
' ,H.TABLE_HEAD_HIGH_RISK ' ||
' ,TRIM(C0.CNTCT_FIRSTNAME) || '' '' || TRIM(C0.CNTCT_SURNAME) wsRaisedBy ' ||
' ,(SELECT COUNT(*) FROM TABLE_EMPLOYEES E WHERE E.TABLE_EMPS_CO_SITE = H.TABLE_HEAD_CO_SITE AND E.TABLE_EMPS_ID = H.TABLE_HEAD_ID) wsNoEmployees ' ||
' ,(SELECT COUNT(*) FROM TABLE_TASKS T WHERE T.TABLE_TASK_CO_SITE = H.TABLE_HEAD_CO_SITE AND T.TABLE_TASK_ID = H.TABLE_HEAD_ID) wsNoActions ' ||
' FROM TABLE_HEADER H ' ||
' LEFT JOIN CONTACTS C0 ' ||
' ON C0.CNTCT_CO_SITE = H.TABLE_HEAD_CO_SITE ' ||
' AND C0.CNTCT_CODE = H.TABLE_HEAD_ORIGINATOR ' ||
' WHERE H.TABLE_HEAD_CO_SITE = ''' || piCoSite || '''' ||
' AND (H.TABLE_HEAD_ID = ''' || piRaciId || '''' || ' OR ''' || piRaciId || ''' = 0) ' ||
' AND (H.TABLE_HEAD_DEPT IN (''' || piDept || ''' ) OR ''' || piDept || ''' IS NULL ) ' ||
' AND (H.TABLE_HEAD_ORIGINATOR IN (' || piUser || ' ) OR ''' || piUser || ''' IS NULL ) ' ||
' AND (H.TABLE_HEAD_STATUS IN (' || piStatus || ' ) OR ''' || piStatus || ''' IS NULL ) ' ||
' ORDER BY TABLE_HEAD_ID ';
dbms_output.put_line(locSql1);
OPEN poRecordset FOR locSql1;
When I copy/paste the locSql1 variable it's nowhere near 32000 chars, but it's getting truncated.
Is there something within the Database to change or am I missing something?
Thanks.
I have a update query in PL/SQL where I need to use OR condition based on itemsetid='XXXX or orgid ='YYYYY' this is because not all tables have these 2 fields so I need to use OR condition. I tried as below but it's not working ,
set serveroutput on size unlimited ;
declare
type item_type
is record (
maxSameas maxattribute.sameasattribute%TYPE,
maxTable maxattribute.objectname%TYPE,
maxAttrib maxattribute.attributename%TYPE
);
Type attribArray is table of item_type;
allAttribs attribArray;
cursor ITEM_ATTRIB_CURSOR is
select a.sameasattribute, a.objectname, a.attributename
from maxattribute a, maxobject b
where a.persistent = 1
and a.objectname = b.objectname
and b.persistent = 1
and ((a.sameasattribute is not null
and a.sameasattribute like 'ITEMNUM')
or (a.attributename = 'ITEMNUM'))
and a.objectname <> 'ITEMHIST'
-- and a.objectname <> 'ITEM'
and b.isView = '0'
order by a.objectname asc, a.attributename asc, a.sameasattribute desc;
type itemXrefType
is record (
currValue itemhist.ITEMNUM%type,
oldValue itemhist.OLDITEMNUM%type
);
type itemXrefTable is table of itemXrefType;
itemXref itemXrefTable;
cursor ITEM_VAL_CURSOR is
select itemnum, olditemnum
from itemhist
where olditemnum is not null and itemsetid='XXXXX';
updateStr varchar2 (4000);
queryStr varchar2 (4000);
tableName varchar2 (30);
attribName varchar2(50);
rowKount NUMBER;
begin
DBMS_OUTPUT.ENABLE(NULL);
-- Fetch Cross Reference Data
open item_val_cursor;
fetch item_val_cursor bulk collect into itemXref;
close item_val_cursor;
-- Fetch all Objects with ITEMNUM attribute
open ITEM_ATTRIB_CURSOR;
fetch ITEM_ATTRIB_CURSOR bulk collect into allAttribs;
close ITEM_ATTRIB_CURSOR;
-- Loop through every Object
for i in allAttribs.first..allAttribs.last loop
tableName := allAttribs(i).maxTable;
if (tableName = 'ITEM') then
attribName := 'ITEMNUM';
else
attribName := allAttribs(i).maxAttrib;
end if;
for j in itemXref.first .. itemXref.last loop
-- For each Item Num, update all objects
queryStr := 'select count (1) from ' || tableName ||
' where ' || attribName || '=' || '''' || itemXref(j).oldValue || '''';
-- Get Count before update
EXECUTE IMMEDIATE queryStr into RowKount;
updateStr := 'update ' || tableName ||
' set ' || attribName || ' = ' || '''' || itemXref(j).currValue
|| ''' where ' || attribName || '=' || '''' || itemXref(j).oldValue || ''' and (itemsetid = ''' || 'XXXX' || ''' or orgid = ''' || 'YYYYY' || ''' ) ''' '''';
--dbms_output.put_line (itemXref(j).currValue || ' ::::' || itemXref(j).oldValue);
dbms_output.put_line (updateStr || ':: Records to be updated is ' || rowKount);
-- Execute the Update
EXECUTE IMMEDIATE updateStr;
-- Commit changes
updateStr := 'Commit';
EXECUTE IMMEDIATE updateStr;
-- Get count after update - should be none!
EXECUTE IMMEDIATE queryStr into RowKount;
dbms_output.put_line (' Count of records after the update is ' || rowKount);
end loop;
end loop; --for i in allAttribs
end;
Thanks in advance!
I want to search some keyword in table but I don't know to which column it is belonging to. I have got one of query for that as follows:
variable val varchar2(10)
exec :val := 'KING'
PL/SQL procedure successfully completed.
SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
SUBSTR (table_name, 1, 14) "Table",
SUBSTR (column_name, 1, 14) "Column" FROM cols,
TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
|| column_name
|| ' from '
|| table_name
|| ' where upper('
|| column_name
|| ') like upper(''%'
|| :val
|| '%'')' ).extract ('ROWSET/ROW/*') ) ) t
ORDER BY "Table"
Searchword Table Column
KING EMP ENAME
but I am not getting appropriate output.I only got output as:
PL/SQL procedure successfully completed. I have tried but I didn't get satisfactory answer. Can anybody please help..?
The easiest query I can write for such scope is something like:
SELECT *
FROM <table>
WHERE UPPER(column1) LIKE UPPER('%' || :val || '%')
OR UPPER(column2) LIKE UPPER('%' || :val || '%')
OR UPPER(column3) LIKE UPPER('%' || :val || '%')
OR UPPER(column4) LIKE UPPER('%' || :val || '%');
In this query I search for value :val in all columns of the table using OR conditions, so if at least one column contains the value the row is fetched
If you have many columns you can write a query that builds the final query for you, like the following:
SELECT 'SELECT * FROM <table> WHERE ' || LISTAGG(column_name || ' LIKE ''%' || :val || '%''', ' OR ') WITHIN GROUP (ORDER BY column_name)
FROM dba_tab_columns
WHERE table_name = '<table>'
The result of this query is the query to execute. Note that Oracle has a limit of 4000 characters for a string field built in a query. If your where condition is too big the query will fail.
In this case, the only alternative is to write a stored procedure that builds the query and returns it in a CLOB variable, here's an example:
CREATE OR REPLACE FUNCTION build_query(in_table_name IN VARCHAR2, in_search IN VARCHAR2) RETURN `CLOB` IS
lc_query CLOB := 'SELECT * FROM ' || in_table_name || ' WHERE 1=0';
BEGIN
FOR c IN (
SELECT *
FROM user_tab_columns
WHERE table_name = in_table_name
ORDER BY column_name
) LOOP
lc_query := lc_query || ' OR ' || c.column_name || ' LIKE ''%' || in_search || '%''';
END LOOP;
RETURN lc_query;
END;
This function will works and generates strings longer than 4000 characters.