Is this MERGE statement is correct...?
Hi all..
MERGE INTO USERMASTER tgt
USING (select * from usermaster ) src
ON ( tgt.USER_ID = src.USER_ID and
tgt.FC_ID=v_tab(i)
WHEN MATCHED
THEN
UPDATE
SET tgt.DELETE_FLG = 0
WHEN NOT MATCHED
THEN
INSERT
(fields
values
(values
Thanks in advance,
Pal
that's not well-formed, but I'm not sure what your intent is. you want one of these:
if origName is in {x, y, z} then
-- true if origName is one of x,y,z
end if
-- or...
if origName is in x or origName is in y or origName is in y then
-- true if orig name is contained in x or in y or in z
end if
Similar Messages
-
Why won't this MERGE statement work?
I am testing out a MERGE statement, which contains a subquery that will return no rows...on this condition, it should insert a record; however I get 0 records merged. Why is this?
Ultimately, the hard-coded values will actually be passed in as parameters. If those a record with those four values is not found, then it should insert.
MERGE INTO tb_slea_election_worksheet A
USING
(SELECT i.slea_year,i.empid,i.bda_sum_sort,i.bda_dtl_sort FROM tb_slea_election_worksheet i
WHERE slea_year = '2008'
AND empid = '6468T'
AND bda_sum_sort = '30'
AND bda_dtl_sort = '9999'
) B
ON (A.slea_year = B.slea_year
AND A.empid =B.empid
AND A.bda_sum_sort = B.bda_sum_sort
AND A.bda_dtl_sort = B.bda_dtl_sort)
WHEN MATCHED THEN
UPDATE SET A.fa_proj_exp_amt = 888
WHEN NOT MATCHED THEN
INSERT (slea_year,empid,bda_sum_sort,bda_dtl_sort,act_exp_lst_yr,fa_proj_exp_amt)
VALUES ( '2008','6468T','30','9999','0','55');A merge statement is just a much more efficient way of doing something like this pl/sql block
DECLARE
l_n NUMBER;
BEGIN
FOR r IN (SELECT pk, col1, col2 FROM source) LOOP
BEGIN
SELECT 1 INTO l_n
FROM target
WHERE pk = r.pk;
UPDATE target
SET col1 = r.col1,
col2 = r.col2
WHERE pk = r.pk;
EXCEPTION WHEN NO_DATA_FOUND THEN
INSERT INTO target
VALUES(r.pk, r.col1, r.col2);
END;
END LOOP;
END;So, if the select from source returns no rows, nothing is going to happen.
John -
Help with this update statement..
Hi everyone,
I am trying to update a column in a table .I need to update that column
with a function that takes patient_nbr and type_x column values as a parameter.
That table has almost "300,000" records. It is taking long time to complete
almost 60 min to 90 min.
Is it usual to take that much time to update that many records?
I dont know why it is taking this much time.Please help with this update statement.
select get_partner_id(SUBSTR(patient_nbr,1,9),type_x) partner_id from test_load;
(it is just taking 20 - 30 sec)
I am sure that it is not the problem with my function.
I tried the following update and merge statements .Please correct me if i am wrong
in the syntax and give me some suggestions how can i make the update statement fast.
update test_load set partner_id = get_partner_id(SUBSTR(patient_nbr,1,9),type_x);
merge into test_load a
using (select patient_nbr,type_x from test_load) b
on (a.patient_nbr = b.patient_nbr)
when matched
then
update
set a.partner_id = get_partner_id(SUBSTR(b.patient_nbr,1,9),b.type_x);
there is a index on patient_nbr column
and the statistics are gathered on this table.Hi Justin,
As requested here are the explain plans for my update statements.Please correct if i am doing anything wrong.
update test_load set partner_id = get_partner_id(SUBSTR(patient_nbr,1,9),type_x);
"PLAN_TABLE_OUTPUT"
"Plan hash value: 3793814442"
"| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |"
"| 0 | UPDATE STATEMENT | | 274K| 4552K| 1488 (1)| 00:00:18 |"
"| 1 | UPDATE | TEST_LOAD | | | | |"
"| 2 | TABLE ACCESS FULL| TEST_LOAD | 274K| 4552K| 1488 (1)| 00:00:18 |"
merge into test_load a
using (select patient_nbr,type_x from test_load) b
on (a.patient_nbr = b.patient_nbr)
when matched
then
update
set a.partner_id = get_partner_id(SUBSTR(b.patient_nbr,1,9),b.type_x);
"PLAN_TABLE_OUTPUT"
"Plan hash value: 1188928691"
"| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |"
"| 0 | MERGE STATEMENT | | 274K| 3213K| | 6660 (1)| 00:01:20 |"
"| 1 | MERGE | TEST_LOAD | | | | | |"
"| 2 | VIEW | | | | | | |"
"|* 3 | HASH JOIN | | 274K| 43M| 7232K| 6660 (1)| 00:01:20 |"
"| 4 | TABLE ACCESS FULL| TEST_LOAD | 274K| 4017K| | 1482 (1)| 00:00:18 |"
"| 5 | TABLE ACCESS FULL| TEST_LOAD | 274K| 40M| | 1496 (2)| 00:00:18 |"
"Predicate Information (identified by operation id):"
" 3 - access("A"."patient_nbr"="patient_nbr")"Please give some suggestions..
what's the best approach for doing the updates for huge tables?
Thanks -
Hi everybody...
MERGE statement without UPDATE or INSERT clause is possible or not
I want to select from one table and update in another table. So i dont want insert statement and i want to do it in single query....possible solutions are requested.
Thanks in advance
palHi..
Thanks for ur reply. For MERGE statement, we have to give UPDATE and INSERT clause. this MERGE statement works without INSERT or UPDATE clause.
Why i am asking is, I want to select how many rows (count(*)) from table1 and based on this count, i have to update in table2
Both tables r different and for select and for update where clauses are different. Both tables r totally different.
I want to do it in single query, so i asked this is possible with MERGE statement without INSERT clause.
Thanks for ur reply -
Where should use Merge Statement in Form
hi experts
in Toad I am using this Merge statement , working accordingly.
I want to use this merge statement in my form where can I use it.
I created a Procedure in Form Named Proc_merge and call it when validate item of *:bankcode*
PROCEDURE proc_merge IS
BEGIN
declare
v_com varchar2(5000);
BEGIN
V_COM := '
Merge into allvouchers trg
using
(select voucher_type,voucher_no,voucher_date,cheque_no,bank_code,narration,debit,credit from(
select pv_voucher_type Voucher_type, pv_no Voucher_No, pv_date Voucher_date, Cheque_no, Acc_code Bank_code, Narration,Debit,Credit
from
(select a.pv_voucher_type,a.pv_no, a.pv_date, a.cheque_no, a.pv_gl_credit_code acc_code , b.ca_title,null Debit,
a.pv_gl_credit_amount Credit, a.Pv_narration Narration
from gl_pv a, ca_gl b where a.pv_gl_credit_Code = b.ca_code and a.pv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
union all
select a.pv_voucher_type,a.pv_voucher_no,a.pv_date,b.cheque_no,a.pv_acc_code,c.ca_title,a.pv_debit, Null credit,a.pv_desc
from payment_detail a, gl_pv b, ca_gl c
where a.pv_voucher_no = b.pv_no
and a.pv_date = b.pv_date
and a.pv_voucher_type = b.pv_voucher_type
and pv_acc_code = c.ca_code and a.pv_debit > 0
and a.pv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
union all
select a.pv_voucher_type, a.pv_voucher_no,a.pv_date, b.cheque_no, a.pv_acc_code, c.ca_title,
null ,a.pv_credit, a.pv_desc
from payment_detail a , gl_pv b , ca_gl c
where a.pv_voucher_no = b.pv_no
and a.pv_date = b.pv_date
and a.pv_acc_code = c.ca_code
and pv_credit >0 and a.pv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
union all
select a.pv_voucher_type, a.pv_no,pv_date,a.cheque_no , a.wht_debt_ac, b.ca_title , null, a.wht_amount, a.wht_narration
from gl_pv a , ca_gl b where a.wht_debt_ac = b.ca_code and wht_amount > 0
and a.pv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
where acc_code = :bankcode
Union all
--------------------- R.Voucher ----------------
select a.rv_voucher_type, a.rv_no, a.rv_date, a.chequeno, b.rv_acc_code, a.rv_narration,b.rv_debit, b.rv_credit
from gl_receipt a, receipt_detail b , ca_gl c
where a.rv_no = b.rv_voucher_no
and a.rv_date = b.rv_date
and b.rv_acc_code = c.ca_code
and b.rv_acc_code = :bankcode
and a.rv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
----------------------- SRV --------------
Union all
select a.vm_voucher_type ,a.vm_no ,a.vm_date,a.chequeno,b.vd_acc_code, b.vd_desc VNARRAION,
b.vd_debit VDEBIT,b.vd_credit VCREDIT
from vouchermaster a, voucherdetail b , ca_gl c
where a.vm_no= b.vd_no
and a.vm_voucher_type = b.vm_voucher_type
and a.vm_date = b.vm_date
and b.vd_acc_code = c.ca_code
and b.vd_acc_code = :bankcode
and a.vm_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
and (a.show_voucher =''Y'' or Show_Voucher is Null)
and a.vm_voucher_type =''SRV''
)) Src
on (trg.v_type = src.voucher_type and trg.v_no = src.voucher_no and trg.v_date = src.voucher_date)
when matched then
update set
trg.v_chq = src.cheque_no, trg.v_bankcode = src.bank_code ,trg.v_debit=src.debit, trg.v_credit=src.credit, trg.v_narration=src.narration
when not matched then
insert (trg.v_type, trg.v_no, trg.v_date, trg.v_chq, trg.v_bankcode, trg.v_debit, trg.v_credit, trg.v_narration)
values (src.voucher_type, src.voucher_no, src.voucher_date, src.cheque_no, src.bank_code, src.debit, src.credit, src.narration)
FORMS_DDL(V_COM);
end;
END;no any result.
please guide me is this right way to do this. or kindly suggest me other ways to using merge statement in form.Hello,
1.) why do you use dynamic SQL here? forms_ddl is a tricky one as it doesn't throw exceptions, so debugging is really fun. And I can't see any justification why this has to be dynamic SQL.
2.) put the whole thing in a stored procedure and call this procedure. write once, run everywhere.
cheers -
I have a merge statement, this executes for all the rows when the procedure is executed. Here i would like to include this merge statement as the part of LOOP so that all records will not get updated for a one time.
how can i change this merge statement to include as the part of LOOP here.
the user id should be the key to update the table USERS in merge statement, the same user id is exists in the bulk collect too..
BEGIN
v_sysdate:= pkg_utilities.fn_sysdate(1) ;
o_Error_Text := 'ORA-Error in updating end date in user_status table ';
tname:= 'user_status';
MERGE INTO user_status r1
USING (
SELECT rowid rid , lead(start_period) OVER (PARTITION by user_id
order by start_period)- 1 new_enddate FROM user_status ) r2
ON ( r1.rowid = r2.rid )
WHEN MATCHED THEN
UPDATE SET end_period = new_enddate ;
OPEN generic_cv4
FOR SELECT
user_id,user_status_type_id
FROM user_status
WHERE end_period IS NULL;
LOOP
FETCH generic_cv4 BULK COLLECT INTO
v_user_id_seq,
v_user_status_new
LIMIT p_array_size;
EXIT WHEN v_user_id_seq.COUNT = 0;
IF v_user_id_seq.COUNT > 0 THEN
o_Error_Text := 'ORA-Error in update user_status type id in users table ';
tname:= 'users';
FORALL I IN v_user_id_seq.FIRST..v_user_id_seq.LAST
UPDATE users
SET user_status_type_id = v_user_status_new(i),
last_upd_date = v_sysdate
WHERE user_id = v_user_id_seq(i);
END IF;
COMMIT;
END LOOP;
v_user_id_seq.delete;
v_user_status_new.delete;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error' ||sqlerrm);
DBMS_OUTPUT.PUT_LINE(o_Error_Text);
v_sql_err :=SQLERRM;
ROLLBACK;
pkg_champ_message_log.champ_message_log ('PKG_MIGRATE_V1_NESTED_MEMBER.p_update_member_status', tname, null,'Nested', v_sql_err,'Error',o_Error_Text,O_STATUS);
END;Now lets talk how can i keep this merge statemnet as the part of the loop. It seems your mind is made up.
Unfortunately, what you're asking makes no sense at all. You can't "loop through a merge statement".
If you don't want to use merge for the entire table at once, the only thing you can do is to break up the table in your USING clause by some sort of range (maybe an account number or whatever). You could then run your code for each range (or even run them in parallel).
The only other option is to not use MERGE at all and duplicate the logic of it within your loop (which is what I said in my first response). -
Can you explain this error message with MERGE statement
Here is the code that gives me headache.
I give you the description of the two tables involved and the error message I get when I run a simple MERGE statement
SQL> desc employees
Name Null? Type
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SQL> desc emp2
Name Null? Type
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME VARCHAR2(25)
1 MERGE INTO emp2 e2
2 USING employees e
3 ON (e2.employee_id = e.employee_id)
4 WHEN MATCHED THEN
5 UPDATE SET
6 e2.employee_id = e.employee_id,
7 e2.last_name = e.last_name,
8 e2.first_name = e.first_name
9 WHEN NOT MATCHED THEN
10 INSERT VALUES
11 (e.employee_id,
12 e.last_name,
13* e.first_name)
14 /
ON (e2.employee_id = e.employee_id)
ERROR at line 3:
ORA-00904: "E2"."EMPLOYEE_ID": invalid identifier
Any responce much appreciatedHi,
Columns going to be updated should not be in 'ON clause' , try to delete the line 6 of your query. By the way, there isno sense to update e2.employee_id = e.employee_id when matched, the equality is already verified.
Nicolas. -
Need suggestion in MERGE Statement
Hi,
I have a scenario like, I have one table T1 with 500,000 to 700,000 records and now I want to check the other table T2 if record exists or not. If record exists with opposite amount ( - or + ) as compare with first table T1 then I need to insert this record from second table T2 to first table T1 and if record is not exists then need to update the flag with 'N' in first table T1. Can MERGE statement will be better solution in this scenario?
Thanks,Here's something generic:
insert into T1 (columns...)
select (columns...)
from T1
where exists (select 1
from T2
where T2.some_key = T1.some_key
and T2.some_value + T1.some_value = 0);
update T1
set some_flag = 'N'
where not exists (select 1
from T2
where T2.some_key = T1.some_key);Sure seems odd though. Are you sure you wrote your original question correctly? -
Hi all,
I am working on oracle9i
I am using the Merge Statement to INS/UPD rows
I am using loops to
I am updating 29 rows as insert and 1 row a update
Values are inserting and updating correctly in table
But in Sql prompt
I am getting the output as
below
12:03:54 SQL> execute Pr_Bdms_Cont_Insupd;
1 rows merged.
1 rows inserted.
1 rows updated.
PL/SQL procedure successfully completed.
But i take out the loop i am getting exact result
12:03:54 SQL> execute Pr_Bdms_Cont_Insupd;
30 rows merged.
29 rows inserted.
1 rows updated.
PL/SQL procedure successfully completed.
Any help
Below is my procedure
and
CREATE OR REPLACE PROCEDURE Pr_EMP_Insupd IS
empID VARCHAR2(7);
CURSOR C_empno IS SELECT empno FROM TEMP WHERE ROWNUM < 30;
REC_BIN C_empid%ROWTYPE;
BEGIN
FOR REC_BIN IN C_empid LOOP
empID := fn_emp_Id(REC_BIN.Bin);-- Calling function
Merge INTO EMP E
BGC
USING (SELECT A.EMP_ID,B.SALARY,B.BONUS
FROM EMP_IN A, TEMP B
WHERE A.EMPNO = B.EMPNO
AND A.EMP_ID = EMPID)NP
ON(E.EMP_ID = NP.EMP_ID)
WHEN MATCHED THEN UPDATE SET E.SALARY = NP.SALARY,
E.BONUS = NP.BONUS
WHEN NOT MATCHED THEN INSERT (E.EMP_ID,E.SALARY,E.BONUS,E.CREATED_DATE)
VALUES (CASE Check_Upd_Ins.merge_counter(Check_Upd_Ins.c_inserting)
WHEN 0 THEN E.EMP_ID
END,
E.SALARY,E.BONUS,SYSDATE);
END LOOP;
/* Use insert count... using ETL Package*/
dbms_output.put_line(Check_Upd_Ins.get_merge_update_count(SQL%rowcount) || ' rows updated.');
dbms_output.put_line(Check_Upd_Ins.get_merge_insert_count || ' rows inserted.');
Check_Upd_Ins.reset_counters;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20000, SQLERRM(SQLCODE));
END Pr_EMP_Insupd;Perhaps I can help you with this piece of code and this link :
MERGE INTO bonuses D
USING (SELECT employee_id, salary, department_id FROM employees
WHERE department_id = 80) S
ON (D.employee_id = S.employee_id)
WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01
WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)
VALUES (S.employee_id, S.salary*0.1);
http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96624/13_elems30.htm#37586
Joel P�rez -
Performance Tuning of a merge statement
Hi,
below query is occupying the temp tablespace(120GB) and explain planis not showing it .
Can someone please help me with this.
explain plan for MERGE INTO BKMAIN.BK_CUST_OD_PEAK_SUM TGT USING
WITH OD_MAIN AS
SELECT
MAX (
CASE
WHEN CUST_BAL_MAX.BK_TRN_TS <= CUST_BAL_TEMP.BK_TRN_TS
AND CUST_BAL_MAX.BK_CUR_BAL_RPT_CCY_AM >= 0
THEN CUST_BAL_MAX.BK_TRN_TS
ELSE NULL
END) T_TMP_TRN_TS,
MIN(
CASE
WHEN CUST_BAL_MAX.BK_TRN_TS >= CUST_BAL_TEMP.BK_TRN_TS
AND CUST_BAL_MAX.BK_CUR_BAL_RPT_CCY_AM >= 0
THEN CUST_BAL_MAX.BK_TRN_TS
ELSE NULL
END) T_TMP_TRN_TS1 ,
CUST_BAL_TEMP.BK_BUS_EFF_DT ,
CUST_BAL_TEMP.BK_CUR_BAL_RPT_CCY_AM ,
CUST_BAL_TEMP.BK_PDAY_CLS_BAL_RPT_CCY_AM ,
CUST_BAL_MAX.N_CUST_SKEY
FROM BKMAIN.BK_CUST_TRN_TM_BAL_SUM CUST_BAL_MAX ,
SELECT TRN_SUM.N_CUST_SKEY ,
TRN_SUM.BK_BUS_EFF_DT ,
TRN_SUM.BK_TRN_TS ,
TRN_SUM.BK_CUR_BAL_RPT_CCY_AM ,
CUST_OD_RSLT.BK_PDAY_CLS_BAL_RPT_CCY_AM
FROM BKMAIN.BK_CUST_TRN_TM_BAL_SUM TRN_SUM,
BKMAIN.BK_CUST_OD_PEAK_SUM CUST_OD_RSLT
WHERE (TRN_SUM.BK_BUS_EFF_DT = '02-APR-2013'
AND TRN_SUM.N_CUST_SKEY = CUST_OD_RSLT.N_CUST_SKEY
AND TRN_SUM.BK_BUS_EFF_DT = CUST_OD_RSLT.BK_BUS_EFF_DT
AND TRN_SUM.BK_CUR_BAL_RPT_CCY_AM= (-1*CUST_OD_RSLT.BK_MAX_OD_RPT_CCY_AM))
CUST_BAL_TEMP
WHERE CUST_BAL_MAX.BK_BUS_EFF_DT='02-APR-2013'
AND CUST_BAL_MAX.N_CUST_SKEY =CUST_BAL_TEMP.N_CUST_SKEY
AND CUST_BAL_MAX.BK_BUS_EFF_DT =CUST_BAL_TEMP.BK_BUS_EFF_DT
GROUP BY CUST_BAL_MAX.N_CUST_SKEY ,
CUST_BAL_TEMP.BK_BUS_EFF_DT ,
CUST_BAL_TEMP.BK_CUR_BAL_RPT_CCY_AM,
CUST_BAL_TEMP.BK_PDAY_CLS_BAL_RPT_CCY_AM
SELECT
N_CUST_SKEY,
BK_BUS_EFF_DT ,
CASE
WHEN T_TMP_TRN_TS IS NOT NULL
THEN
SELECT CUST_BAL.BK_CUR_BAL_END_TS
FROM BKMAIN.BK_CUST_TRN_TM_BAL_SUM CUST_BAL
WHERE CUST_BAL.BK_BUS_EFF_DT='02-APR-2013'
AND CUST_BAL.N_CUST_SKEY = OD_MAIN.N_CUST_SKEY
AND CUST_BAL.BK_TRN_TS = OD_MAIN.T_TMP_TRN_TS
WHEN (T_TMP_TRN_TS IS NULL
AND OD_MAIN.BK_PDAY_CLS_BAL_RPT_CCY_AM < 0)
THEN BK_FN_GET_STRT_EOD_BUS_TS(1, '02-APR-2013','S')
WHEN (T_TMP_TRN_TS IS NULL
AND OD_MAIN.BK_PDAY_CLS_BAL_RPT_CCY_AM >= 0)
THEN
SELECT MIN(CUST_BAL.BK_TRN_TS)
FROM BKMAIN.BK_CUST_TRN_TM_BAL_SUM CUST_BAL
WHERE CUST_BAL.BK_BUS_EFF_DT='02-APR-2013'
AND CUST_BAL.N_CUST_SKEY = OD_MAIN.N_CUST_SKEY
AND CUST_BAL.BK_OD_FL ='Y'
END T_MAX_OD_STRT_TS,
CASE
WHEN T_TMP_TRN_TS1 IS NOT NULL
THEN
SELECT CUST_BAL.BK_CUR_BAL_STRT_TS
FROM BKMAIN.BK_CUST_TRN_TM_BAL_SUM CUST_BAL
WHERE CUST_BAL.BK_BUS_EFF_DT='02-APR-2013'
AND CUST_BAL.N_CUST_SKEY = OD_MAIN.N_CUST_SKEY
AND CUST_BAL.BK_TRN_TS = OD_MAIN.T_TMP_TRN_TS1
WHEN (T_TMP_TRN_TS1 IS NULL )
THEN BK_FN_GET_STRT_EOD_BUS_TS(1, '02-APR-2013','E')
END T_MAX_OD_END_TS
FROM OD_MAIN
) SRC ON(TGT.N_CUST_SKEY = SRC.N_CUST_SKEY AND TGT.BK_BUS_EFF_DT = SRC.BK_BUS_EFF_DT AND TGT.BK_BUS_EFF_DT = '02-APR-2013')
WHEN MATCHED THEN
UPDATE
SET BK_MAX_OD_STRT_TS = T_MAX_OD_STRT_TS,
BK_MAX_OD_END_TS = T_MAX_OD_END_TS;
set linesize 2000;
select * from table( dbms_xplan.display );
PLAN_TABLE_OUTPUT
Plan hash value: 2341776056
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | MERGE STATEMENT | | 1 | 54 | 2035 (1)| 00:00:29 |
| 1 | MERGE | BK_CUST_OD_PEAK_SUM | | | | |
|* 2 | TABLE ACCESS BY INDEX ROWID | BK_CUST_TRN_TM_BAL_SUM | 1 | 35 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | PK_BK_CUST_TRN_TM_BAL_SUM | 1 | | 3 (0)| 00:00:01 |
|* 4 | TABLE ACCESS BY INDEX ROWID | BK_CUST_TRN_TM_BAL_SUM | 1 | 35 | 4 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | PK_BK_CUST_TRN_TM_BAL_SUM | 1 | | 3 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
| 6 | SORT AGGREGATE | | 1 | 26 | | |
|* 7 | TABLE ACCESS BY INDEX ROWID | BK_CUST_TRN_TM_BAL_SUM | 1 | 26 | 9 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | PK_BK_CUST_TRN_TM_BAL_SUM | 5 | | 3 (0)| 00:00:01 |
| 9 | VIEW | | | | | |
| 10 | NESTED LOOPS | | | | | |
| 11 | NESTED LOOPS | | 1 | 173 | 2035 (1)| 00:00:29 |
| 12 | VIEW | | 1 | 61 | 2033 (1)| 00:00:29 |
| 13 | SORT GROUP BY | | 1 | 85 | 2033 (1)| 00:00:29 |
| 14 | NESTED LOOPS | | | | | |
| 15 | NESTED LOOPS | | 1 | 85 | 2032 (1)| 00:00:29 |
|* 16 | HASH JOIN | | 1 | 54 | 2024 (1)| 00:00:29 |
PLAN_TABLE_OUTPUT
|* 17 | TABLE ACCESS STORAGE FULL| BK_CUST_OD_PEAK_SUM | 18254 | 410K| 118 (0)| 00:00:02 |
|* 18 | TABLE ACCESS STORAGE FULL| BK_CUST_TRN_TM_BAL_SUM | 370K| 10M| 1904 (1)| 00:00:27 |
|* 19 | INDEX RANGE SCAN | PK_BK_CUST_TRN_TM_BAL_SUM | 5 | | 2 (0)| 00:00:01 |
|* 20 | TABLE ACCESS BY INDEX ROWID| BK_CUST_TRN_TM_BAL_SUM | 3 | 93 | 8 (0)| 00:00:01 |
|* 21 | INDEX RANGE SCAN | PK_BK_CUST_OD_PEAK_SUM | 1 | | 1 (0)| 00:00:01 |
| 22 | TABLE ACCESS BY INDEX ROWID | BK_CUST_OD_PEAK_SUM | 1 | 112 | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
2 - filter("CUST_BAL"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
3 - access("CUST_BAL"."N_CUST_SKEY"=:B1 AND "CUST_BAL"."BK_TRN_TS"=:B2)
4 - filter("CUST_BAL"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
5 - access("CUST_BAL"."N_CUST_SKEY"=:B1 AND "CUST_BAL"."BK_TRN_TS"=:B2)
7 - filter("CUST_BAL"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"CUST_BAL"."BK_OD_FL"='Y')
8 - access("CUST_BAL"."N_CUST_SKEY"=:B1)
16 - access("TRN_SUM"."N_CUST_SKEY"="CUST_OD_RSLT"."N_CUST_SKEY" AND
"TRN_SUM"."BK_BUS_EFF_DT"="CUST_OD_RSLT"."BK_BUS_EFF_DT" AND
"TRN_SUM"."BK_CUR_BAL_RPT_CCY_AM"=(-1)*"CUST_OD_RSLT"."BK_MAX_OD_RPT_CCY_AM")
17 - storage("CUST_OD_RSLT"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
PLAN_TABLE_OUTPUT
filter("CUST_OD_RSLT"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
18 - storage("TRN_SUM"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
filter("TRN_SUM"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
19 - access("CUST_BAL_MAX"."N_CUST_SKEY"="TRN_SUM"."N_CUST_SKEY")
20 - filter("CUST_BAL_MAX"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss')
AND "CUST_BAL_MAX"."BK_BUS_EFF_DT"="TRN_SUM"."BK_BUS_EFF_DT")
21 - access("TGT"."N_CUST_SKEY"="N_CUST_SKEY" AND "TGT"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02
00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
filter("TGT"."BK_BUS_EFF_DT"=TO_DATE(' 2013-04-02 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
53 rows selected.Hi
sb92075 wrote:
it appears that the STATISTICS do NOT reflect reallity; or do you really have many tables with 1 row?not necessarily (and not even likely)
1) explain plan shows expected number of rows after filters are applied, so even if stats are perfectly correct, but predicates are correlated, then it's easy to get cardinality = 1 because the optimizer has no way of knowing correlations between columns (unless you're in 11g and you have collected exteded stats on this colgroup)
2) in explain plan, cardinalities of driven operations are show per 1 iterantion. E.g.:
NESTED LOOP cardinality = 1,000,000
TABLE ACCESS FULL A cardinality = 1,000,000
TABLE ACCESS BY ROWID B cardinality = 1
INDEX UNIQUE SCAN PK$B cardinality = 1doesn't mean that the optimizer expects to find 1 row in table B, with or without filters, it means that there will be 1 row per each of 1,000,000 iterations.
In this specific case, the most suspicious operation in the plan is HASH JOIN 16: first, because it's highly unusual to have 18k rows in one table and 370k in another
and find only 1 match; second, because it's a 3-column join, which probably explains why the join cardinality is estimated so low.
Often, such problems are mitigated by multicolumn join sanity checks, so maybe the OP is either on an old version of Oracle that doesn't have these checks, or these checks are disabled for some reason.
Best regards,
Nikolay -
HOW TO CUSTOMIZE MERGE STATEMENT
Hi Everybody,
I want to create an interface that works as the sql statement shown below. How can i do this?
merge into gecici.xx1 a
using ( select * from gecici.xx2 ) b
on ( a.verde_kod=b.verde_kod)
when matched then
update set A.ilk_kay_tar= ( case when b.kayitli=1 and a.kayitli=0 then B.KAYITLILIK_TARIHI else A.ilk_kay_tar end)
the sql statement is correct i tested it.
With OWB this is simple , but in odi i haven't found a solution yet.
Any help will be appreciated.
thx
tolgaHi Himanshu,
Thx for your mail. Insert part of this statement is not important , the problem is to correctly put the case statement. Although i put in the mapping the generated code does not do what i want.
ınstead of using my source and target tables, th egenerated code uses flow tables which does not create the same result.
what i try to do here is to add new column to a table which stores the first_registration_date. And i want to update this column only once , when a customer register himself at the first time.
Thx
tolga -
Hi
I am using a merge statement where i am updating and inserting records in table 2 from table 1.
I want to log the no. of rows updated and new rows inserted in the log table.
If i am not wrong, we can use sql%rowcount but i need help as how to use this statement.
Please suggest a solution.
Thanksuser11018028 wrote:
Will the sql%rowcount will give the no. of updated rows OR no. of newly inserted rows OR the sum of both in case of a merge statement.Total number of rows that changed (SUM). -
Question on passing string values to Partition clause in a merge statement
Hello All,
I am using the below code to update specific sub-partition data using oracle merge statements.
I am getting the sub-partition name and passing this as a string to the sub-partition clause.
The Merge statement is failing stating that the specified sub-partition does not exist. But the sub-partition do exists for the table.
We are using Oracle 11gr2 database.
Below is the code which I am using to populate the data.
declare
ln_min_batchkey PLS_INTEGER;
ln_max_batchkey PLS_INTEGER;
lv_partition_name VARCHAR2 (32767);
lv_subpartition_name VARCHAR2 (32767);
begin
FOR m1 IN ( SELECT (year_val + 1) AS year_val, year_val AS orig_year_val
FROM ( SELECT DISTINCT
TO_CHAR (batch_create_dt, 'YYYY') year_val
FROM stores_comm_mob_sub_temp
ORDER BY 1)
ORDER BY year_val)
LOOP
lv_partition_name :=
scmsa_handset_mobility_data_build.fn_get_partition_name (
p_table_name => 'STORES_COMM_MOB_SUB_INFO',
p_search_string => m1.year_val);
FOR m2
IN (SELECT DISTINCT
'M' || TO_CHAR (batch_create_dt, 'MM') AS month_val
FROM stores_comm_mob_sub_temp
WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val)
LOOP
lv_subpartition_name :=
scmsa_handset_mobility_data_build.fn_get_subpartition_name (
p_table_name => 'STORES_COMM_MOB_SUB_INFO',
p_partition_name => lv_partition_name,
p_search_string => m2.month_val);
DBMS_OUTPUT.PUT_LINE('The lv_subpartition_name => '||lv_subpartition_name||' and lv_partition_name=> '||lv_partition_name);
IF lv_subpartition_name IS NULL
THEN
DBMS_OUTPUT.PUT_LINE('INSIDE IF => '||m2.month_val);
INSERT INTO STORES_COMM_MOB_SUB_INFO T1 (
t1.ntlogin,
t1.first_name,
t1.last_name,
t1.job_title,
t1.store_id,
t1.batch_create_dt)
SELECT t2.ntlogin,
t2.first_name,
t2.last_name,
t2.job_title,
t2.store_id,
t2.batch_create_dt
FROM stores_comm_mob_sub_temp t2
WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val
AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
m2.month_val;
ELSIF lv_subpartition_name IS NOT NULL
THEN
DBMS_OUTPUT.PUT_LINE('INSIDE ELSIF => '||m2.month_val);
MERGE INTO (SELECT *
FROM stores_comm_mob_sub_info
SUBPARTITION (lv_subpartition_name)) T1
USING (SELECT *
FROM stores_comm_mob_sub_temp
WHERE TO_CHAR (batch_create_dt, 'YYYY') =
m1.orig_year_val
AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
m2.month_val) T2
ON (T1.store_id = T2.store_id
AND T1.ntlogin = T2.ntlogin)
WHEN MATCHED
THEN
UPDATE SET
t1.postpaid_totalqty =
(NVL (t1.postpaid_totalqty, 0)
+ NVL (t2.postpaid_totalqty, 0)),
t1.sales_transaction_dt =
GREATEST (
NVL (t1.sales_transaction_dt,
t2.sales_transaction_dt),
NVL (t2.sales_transaction_dt,
t1.sales_transaction_dt)),
t1.batch_create_dt =
GREATEST (
NVL (t1.batch_create_dt, t2.batch_create_dt),
NVL (t2.batch_create_dt, t1.batch_create_dt))
WHEN NOT MATCHED
THEN
INSERT (t1.ntlogin,
t1.first_name,
t1.last_name,
t1.job_title,
t1.store_id,
t1.batch_create_dt)
VALUES (t2.ntlogin,
t2.first_name,
t2.last_name,
t2.job_title,
t2.store_id,
t2.batch_create_dt);
END IF;
END LOOP;
END LOOP;
COMMIT;
end;
Much appreciate your inputs here.
Thanks,
MK.I've not used partitioning, but I do not see MERGE supporting a variable as a partition name in
MERGE INTO (SELECT *
FROM stores_comm_mob_sub_info
SUBPARTITION (lv_subpartition_name)) T1
USING ... I suspect it is looking for a partition called lv_subpartition_name.
I also don't see why you need that partition name - the ON clause should be able to identify the partition's criteria. -
Issue while using SUBPARTITION clause in the MERGE statement in PLSQL Code
Hello All,
I am using the below code to update specific sub-partition data using oracle merge statements.
I am getting the sub-partition name and passing this as a string to the sub-partition clause.
The Merge statement is failing stating that the specified sub-partition does not exist. But the sub-partition do exists for the table.
We are using Oracle 11gr2 database.
Below is the code which I am using to populate the data.
declare
ln_min_batchkey PLS_INTEGER;
ln_max_batchkey PLS_INTEGER;
lv_partition_name VARCHAR2 (32767);
lv_subpartition_name VARCHAR2 (32767);
begin
FOR m1 IN ( SELECT (year_val + 1) AS year_val, year_val AS orig_year_val
FROM ( SELECT DISTINCT
TO_CHAR (batch_create_dt, 'YYYY') year_val
FROM stores_comm_mob_sub_temp
ORDER BY 1)
ORDER BY year_val)
LOOP
lv_partition_name :=
scmsa_handset_mobility_data_build.fn_get_partition_name (
p_table_name => 'STORES_COMM_MOB_SUB_INFO',
p_search_string => m1.year_val);
FOR m2
IN (SELECT DISTINCT
'M' || TO_CHAR (batch_create_dt, 'MM') AS month_val
FROM stores_comm_mob_sub_temp
WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val)
LOOP
lv_subpartition_name :=
scmsa_handset_mobility_data_build.fn_get_subpartition_name (
p_table_name => 'STORES_COMM_MOB_SUB_INFO',
p_partition_name => lv_partition_name,
p_search_string => m2.month_val);
DBMS_OUTPUT.PUT_LINE('The lv_subpartition_name => '||lv_subpartition_name||' and lv_partition_name=> '||lv_partition_name);
IF lv_subpartition_name IS NULL
THEN
DBMS_OUTPUT.PUT_LINE('INSIDE IF => '||m2.month_val);
INSERT INTO STORES_COMM_MOB_SUB_INFO T1 (
t1.ntlogin,
t1.first_name,
t1.last_name,
t1.job_title,
t1.store_id,
t1.batch_create_dt)
SELECT t2.ntlogin,
t2.first_name,
t2.last_name,
t2.job_title,
t2.store_id,
t2.batch_create_dt
FROM stores_comm_mob_sub_temp t2
WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val
AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
m2.month_val;
ELSIF lv_subpartition_name IS NOT NULL
THEN
DBMS_OUTPUT.PUT_LINE('INSIDE ELSIF => '||m2.month_val);
MERGE INTO (SELECT *
FROM stores_comm_mob_sub_info
SUBPARTITION (lv_subpartition_name)) T1 --> Issue Here
USING (SELECT *
FROM stores_comm_mob_sub_temp
WHERE TO_CHAR (batch_create_dt, 'YYYY') =
m1.orig_year_val
AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
m2.month_val) T2
ON (T1.store_id = T2.store_id
AND T1.ntlogin = T2.ntlogin)
WHEN MATCHED
THEN
UPDATE SET
t1.postpaid_totalqty =
(NVL (t1.postpaid_totalqty, 0)
+ NVL (t2.postpaid_totalqty, 0)),
t1.sales_transaction_dt =
GREATEST (
NVL (t1.sales_transaction_dt,
t2.sales_transaction_dt),
NVL (t2.sales_transaction_dt,
t1.sales_transaction_dt)),
t1.batch_create_dt =
GREATEST (
NVL (t1.batch_create_dt, t2.batch_create_dt),
NVL (t2.batch_create_dt, t1.batch_create_dt))
WHEN NOT MATCHED
THEN
INSERT (t1.ntlogin,
t1.first_name,
t1.last_name,
t1.job_title,
t1.store_id,
t1.batch_create_dt)
VALUES (t2.ntlogin,
t2.first_name,
t2.last_name,
t2.job_title,
t2.store_id,
t2.batch_create_dt);
END IF;
END LOOP;
END LOOP;
COMMIT;
end;
Much appreciate your inputs here.
Thanks,
MK.
(SORRY TO POST THE SAME QUESTION TWICE).
Edited by: Maddy on May 23, 2013 10:20 PMDuplicate question
-
Error executing a stored procedure from SSIS using the MERGE statement between databases
Good morning,
I'm trying to execute from SSIS a stored procedure that compares the content of two tables on different databases in the same server and updates one of them. To perform this action, I've created a stored procedure in the destination database and I'm
comparing the data between tables with the MERGE statement. When I execute the procedure on the destination database the error that I obtain is:
"Msg 916, Level 14, State 1, Procedure RefreshDestinationTable, Line 13
The server principal "XXXX" is not able to access the database "XXXX" under the current security context."
Some things to take in account:
1. I've created a temporary table on the same destination database to check if the problem was on the MERGE statement and it works fine.
2. I've created the procedure with the option "WITH EXECUTE AS DBO".
I've read that it can be a problem of permissions but I don't know if I'm executing the procedure from SSIS to which user/login I should give permissions and which.
Could you give me some tip to continue investigating how to solve the problem?
Thank you,
VirgilioRead Erland's article http://www.sommarskog.se/grantperm.html
Best Regards,Uri Dimant SQL Server MVP,
http://sqlblog.com/blogs/uri_dimant/
MS SQL optimization: MS SQL Development and Optimization
MS SQL Consulting:
Large scale of database and data cleansing
Remote DBA Services:
Improves MS SQL Database Performance
SQL Server Integration Services:
Business Intelligence
Maybe you are looking for
-
Microsoft word: rotate photos. Apple: rename photos
Hello, I am new to apple, and English... I have two problems: Microsoft word. I want to rotate a photo inserted in one of my word document, I can see the function "rotate" in the tool box but this is not working. When I click on the rotate option, ev
-
Service p.o. not generated
hi gurus, as i m settling the shipment cost in vi02 system is not automatically generating the p.o. which it should generate ,i belive. i've done all the configuration settings in img i m not able to know what triggers automatic p.o. genation may be
-
Oracle 10xe on Amazon EC2 - pricing
Hello I want to try creating an Oracle 10gXE on the Amazon EC2 for proof of concept, which means I need it to be free or close to I've created my Amazon EC2 setup, and checked the pricing which i believe is close to 0 as long as the load is very litt
-
Firefox 2.0 in Portuguese [SOLVED]
Hello, Before the 2.0 version it was very easy to find a "xpi" file and get the Portuguese Firefox translation working. But I've been searching for weeks for that "xpi" compatible with the version 2.0 with the Portuguese (don't matter if Brazilian or
-
Hi gurus, My problem is, i have a two dimensions expansion in rows, i want to show the combinations of members of the two dimensions that had any value different from zero last year. So i insert in the suppress expansion's suppress cell XXXX.TOTAL of