Debugging this merge statement
EMPL of MERGE IN one
USING (SELECT *)
T) b
WE (a.empno = b.empno)
WHEN MATCHED THEN
UPDATE
SET a.ename = b.ename, a.job = b.job,
a.Mgr = b.mgr, a.hiredate = b.hiredate, a.sal = b.sal,
a.comm b.com, a.deptno = b.deptno =
WHEN NOT MATCHED THEN
INSERT (a.empno, a.ename, a.job, a.mgr, a.hiredate, a.sal, a.comm,
a.DEPTNO)
VALUES (b.empno, b.ename, b.job, b.mgr, b.hiredate, b.sal, b.b.a., specialization
b.DEPTNO);
Note t is import table that has data of new employees and empl is the table that store data for all employees and it is the main table, above 2 tables are replica of scott.emp with data
Problem when I'm executing the merge statement preceding the session is the gel
Solution ?
Perhaps another session has locked some rows in the emp table?
Try
select * from empl where empno in (select empno from t_imp) for update nowait;
When you get an error such as ORA-00054, another session is locking of lines that you want to update.
Hope that helps,
dhalek
Tags: Database
Similar Questions
-
problem compiling with MERGE statement
What is the problem with this merge statement?
When I compile I get the message
met symbol IN when one of the following expected
*:= . (@ %; < a SQL > *)
MERGE INTO PF_REP_TEMP HAS
WITH THE HELP OF PF_REP_SKS B
WE (a. pf_userid = "FINP' AND B.pfbatch = 'F99' and B.pfstfno = A.pf_staffno
and B.pfcc = "7" and B.pftransmy = A.mmyy and B.slno = A.s_no)
When matched then
game update
a.pfwdrlm = b.pfwdrlm,
a.PFRC = b.PFRC;
Help, please
(version of the form is 10g, 11g database version)How to perform a merge into forms button pressed trigger command
-
ORA 22813 in the merge statement
Hi the gems... Good afternoon...
My version of the database is 11.2.0.1.0 Solaris 64-bit OS.
I am facing a ' ORA-22813: value of the operand exceeds the limits of the system "during the execution of a procedure.
I used loggers and found that it is getting failed in a MERGE statement.
This merge statement is used to merge a table with a collection. the code is as below:
Function GET_BALANCE_HIST (V_MERGE_REC) parameter is an array type.MERGE /*+ INDEX(P BALANCE_HISTORIC_INDEX) */ INTO BALANCE_HOLD_HISTORIC P USING TABLE(GET_BALANCE_HIST(V_MERGE_REC)) M ON (P.CUSTOMER_ID = M.CUSTOMER_ID AND P.BOOK_ID = M.BOOK_ID AND P.PRODUCT_ID = M.PRODUCT_ID AND P.SUB_BOOK_ID = M.SUB_BOOK_ID AND) WHEN MATCHED THEN UPDATE <set .....> WHEN NOT MATCHED THEN INSERT<.....>
Now GET_BALANCE_HIST (V_MERGE_REC) is a function in the pipeline and we used that because the V_MERGE_REC collection can become huge with data.
This process worked very well since the beginning, but since yesterday, it was constantly throwing 22813 ORA error in this line.
Help, please... Thanks in advance...Gogol wrote:
The code flow is as below:There is a sql query, the output is a set of some several lakes of records. Now we take the result of the sql query in a collection with a limit of 1000 (FETCH cur_sql COLLECT LOOSE v_balance_rec LIMIT 1000). Then we do a lot of processing, the calculation of this collection.
After the treatment and calculation, we are filling another collection this collection transformed (V_BALANCE_REC) (V_MERGE_REC). Thus, if the loop iterates for 1000 times, then the V_MERGE_REC is filled with records of 1000 * 500 = 500000 processed.
And then we go to this huge V_MERGE_REC collection as a parameter to this function.
Don't know what are the Lakes. Please use International English.
Why can't do you math in a SQL query?
If it's really too hard to do in SQL (SQL queries can perform a treatment fairly complex), then I would look to Scripture
results of a table and use it. -
Different result by using the MERGE statement
I have 2 SQL statements:
MERGE INTO PT_CQS_AGGR APC
With the HELP of PT_CQS_AGGR_TEMP Lady
WE (concat (concat(pca.from_city_id,pca.to_city_id), pca.query_timestamp_hh) = concat (concat(pcah.from_city_id,pcah.to_city_id), pcah.query_timestamp_hh))
WHEN MATCHED THEN
Setting a DAY SET pca.search_count = pca.search_count + pcah.search_count
WHEN NOT MATCHED THEN
VALUES of INSERTION (to_city_id, query_timestamp_hh, from_city_id, search_count) (pcah.from_city_id, pcah.to_city_id, pcah.query_timestamp_hh, pcah.search_count);
AND
MERGE INTO PT_CQS_AGGR APC
With the HELP of PT_CQS_AGGR_TEMP Lady
WE (pca.from_city_id = pcah.from_city_id AND pca.to_city_id = pcah.to_city_id AND pca.query_timestamp_hh = pcah.query_timestamp_hh)
WHEN MATCHED THEN
Setting a DAY SET pca.search_count = pca.search_count + pcah.search_count
WHEN NOT MATCHED THEN
VALUES of INSERTION (to_city_id, query_timestamp_hh, from_city_id, search_count) (pcah.from_city_id, pcah.to_city_id, pcah.query_timestamp_hh, pcah.search_count);
First statement correctly the merged data, but use FULL TABLE SCANS, so it's rather slow. Second statement using a UNIQUE INDEX on the columns from_city_id, to_city_id, and query_timestamp_hh on the MAP of EXPLAIN, but during the execution of I've got ORA-00001: unique constraint (PODOWNER. IDX_CQS_AGGR_3COL) violated. What is the problem with the second statement - especially with this line:
WE (pca.from_city_id = pcah.from_city_id AND pca.to_city_id = pcah.to_city_id AND pca.query_timestamp_hh = pcah.query_timestamp_hh) Can I use a more complex condition in the MERGE statement? Because it seems that not all the conditions have been taken...
???
Select pcah.from_city_id, pcah.to_city_id, PT_CQS_AGGR_TEMP Lady pcah.query_timestamp_hh
less
Select pca.from_city_id, pca.to_city_id, pca.query_timestamp_hh PT_CQS_AGGR pca
somewhere the conditions limiting the time.
(or whatever the columns make up the stress of failing)
In addition, select for each column in the constraint of failure where the column is null. If one of these columns is null, equality fails, even if both are null, because null <> null. So you will get a "no match" if all values are the same and it is set to null.
Edit: Oh, slap forehead, that is why one works and the complete analysis. As SomeoneElse said, it normalizes the type of data and concatenates, comparison null to no effect and refusing all usual index.
-
MERGE statement is increment the sequence. It problem?
Hi allI use a merge statement to update thousands of data in a table. If the criteria does not match (WHEN NOT MATCHED) I wrote an insert statement that contains a reference to the sequence. And it works very well.
My question is, will this increment also sequence even though it won't insert the statement in the script of fusion. I think it will be. Right?
Say, I update 20K record will be the sequence also increment by 20 times k. If his past all work around.
Thanks in advance.
Here is a less effective solution to your problem that creates a function to get the value of the following sequence, but I agree with Justin cave that because of the cache you must lose the values.
SQL > CREATE SEQUENCE s_emp;
Order of creation.
SQL > CREATE or REPLACE FUNCTION s_emp_nextval
2 RETURN NUMBER
3 AS
4 v_nextval NUMBER;
5 BEGIN
6. SELECT s_emp.nextval
7 INTO v_nextval
8 DOUBLE;
9 v_nextval of RETURN;
10 END;
11.
The function is created.
SQL > MERGE IN emp t (USING)
2. SELECT empno, ename
3 FROM emp) s
4. WE (t.empno = s.empno)
5. WHEN MATCHED THEN
UPDATE 6
7 SET t.ename = s.ename
8 WHEN NOT MATCHED THEN
9 INSERT (empno, ename)
10 VALUES (s_emp_nextval, 'SMITH');
14 lines merged.
SQL > SELECT s_emp. NEXTVAL
2 FROM dual;
NEXTVAL
----------
1
-
Error in the Merge statement using dblink
Hello
I am facing the following error when you use the merge statement using the dblink.
ORA-02069: global_names must be set to true for this operation parameter.
I can use the same dblink in my select insert and update statements but when I try to use merge then he invites the error said, is also not any syntax error as same statement can be used on the same tables of database instead of dblink.
Please suggest any help will be much appreciated.
Thanks in advance
Hi Aqeel
If insert and update statements work well through links db, then it should not be a problem with the merge statement. But if you are faced with the question, so please check the entire sql statement with tnsnames on both sides. Please share the tnsnames for the two dbs with dblink ddl.
Concerning
Jihane Narain Sylca
-
Hi all
I am facing a problem of failure to merge because of duplicate statement in the Source table. In a merge statement, what I understand is if the Update statement in which corresponding clause contains WHERE predicates, they are pushed upward to filter the lines of the clause?
In order to understand, I tried to frame a test case to model how my real scenario is:
create table tab_src (col1, col2 number number, number of col3, col4 varchar2 (5));
create table tab_des (col1, col2 number number, number of col3, col4 varchar2 (5));insert into tab_src values (1, 1, 1, 'AAA');
insert into tab_src values (1, 1, 0, "AAB");insert into tab_des values (1, 1, -1, null);
explain plan for
merge into tab_des d
a_l'_aide_de)
Select *.
of tab_src
where col3 is not null
) s
on (d.col1 = s.col1
and d.col2 = s.col2
)
When matched then
update the value of col4 = s.col4
where d.col3 is not null;Select *.
table (dbms_xplan.display (null, null, 'ALL'));Hash value of plan: 3751341164
--------------------------------------------------------------------------------
| ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |
--------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 1. 60. 7 (15) | 00:00:01 |
| 1. MERGE | TAB_DES | | | | |
| 2. VIEW | | | | | |
|* 3 | HASH JOIN | | 1. 98. 7 (15) | 00:00:01 |
| 4. TABLE ACCESS FULL | TAB_DES | 1. 55. 3 (0) | 00:00:01 |
|* 5 | TABLE ACCESS FULL | TAB_SRC | 2. 86. 3 (0) | 00:00:01 |
--------------------------------------------------------------------------------
Name of the query block / Alias object (identified by the operation identity card):
-------------------------------------------------------------
1 MRG$ 1
3 SALT$ F5BB74E1
4 SALT$ F5BB74E1 / D@SEL$1
5. SALT$ F5BB74E1 / TAB_SRC@SEL$2
Information of predicates (identified by the operation identity card):
---------------------------------------------------
3 - access("D".") COL1 "=" TAB_SRC. " "" COL1 "AND
"D"." COL2 "=" TAB_SRC. " ("" COL2 ")
5 - filter ("COL3" IS NOT NULL)
Projection of the column information (identified by the operation identity card):
-----------------------------------------------------------
1 SYSDEF [4], SYSDEF [32720], SYSDEF [1], SYSDEF [76], SYSDEF [32720]
2 - « D ». "COL3" [NO.22], "S" "." " COL4 ' [VARCHAR2, 5].
3. (#keys = 2) "D". "COL1" [NO.22], "TAB_SRC" "." " COL1 '[NUMBER, 22],
"D"." COL2"[NO.22],"TAB_SRC ". ' COL2 '[NUMBER, 22],
« D ». ROWID [ROWID, 10], "D". "COL4" [VARCHAR2, 5], "D" "." " COL3 '[NUMBER, 22],
'TAB_SRC '. "COL4" [VARCHAR2, 5], 'COL3 '[NUMBER, 22] "
4 - « D ». ROWID [ROWID, 10], "D". ' COL1 '[NUMBER, 22],
"D"." COL2"[NO.22],"D ". "COL3" [NO.22], "D" "." " COL4 ' [VARCHAR2, 5].
5. "TAB_SRC". "COL1" [NO.22], "TAB_SRC" "." " COL2 '[NUMBER, 22],
'COL3' [NO.22], "TAB_SRC". "COL4" [VARCHAR2, 5].
Note
-----
-dynamic sampling used for this statement
The predicate information section made no reference to the column COL3 to the Destination table. Then it would be correct to conclude that the where predicates in the UPDATE clause will play no role in the identification of lines of data from source table/query?
I use oracle 10.2.0.5.
That's right, the where clauses are applied as the update is done, they will not be part of the condition WE which identifies the lines merge. This is why you must make sure that your condition IT only joined the lines to merge and there are no duplicates.
-
Hi Experts,
I write under the MERGE statement. In this cardinality of the table_a table_b is 1:2. That is, each record of table_b corresponds to 2 records in table_a based on columns in CLAUSE.
Well, this query throws below error.
-Error-
ORA-12801: error reported in the P011 parallel query server
ORA-30926: failed to get a stable set of rows in the source tables
However, the same statement runs successfully what tip PARALLEL is removed altogether. (There are no duplicates in table_b based on unity, group, loc columns.)
Please sugget if anything look his place here or causes possible.
-Request-
MERGE / * + PARALLEL (8) * /.
IN table_a a
With the HELP of table_b b
ON (a.unit = b.unit
AND a.group = b.group
AND a.loc = b.loc)
WHEN MATCHED
THEN UPDATE
SET a.u_pushonly = b.u_pushonly
a.u_seasonind = b.u_seasonind,
a.eff = BOX
WHEN b.u_season_start_dt <>TO_DATE('01/01/1970','DD/MM/YYYY')
OR b.u_season_end_dt <>TO_DATE('01/01/1970','DD/MM/YYYY')
OR b.u_pushonly = 1
THEN more GRAND (NVL (b.u_assortment_start_dt, TO_DATE('01/01/1970','DD/MM/YYYY'))
b.u_season_start_dt)
Of OTHER NVL (b.u_assortment_start_dt, TO_DATE('01/01/1970','DD/MM/YYYY'))
END;
kendenny wrote:
Fusion requires that columns be unique in both tables. Given that you only update was not insert is not put in correspondence, then you can use a single update statement.
I don't think so, it requires only NEW data is unique. Informal argument: a single line in the new table can update several lines in the table of old, but you can not use several lines in the new table to update a single row in the old table.
However, I wonder if something went wrong with the parallelism so that the lines with the same VALUES for the data (old) table_a has been distributed through many slaves, leading to several slaves, trying to update each on the other lines. (I don't see how this could happen, but it's one of the problems with bugs - if she should not deceive you, it can be difficult to imagine how it's bad).
To the OP - this sounds like something, you need to trigger an SR for (after a search of MOS).
Concerning
Jonathan Lewis
-
Question about the transition from string values to the Partition clause in a merge statement
Hi all
I use the code to update the data of specific secondary partition using oracle merge statements below.
I'm getting the name of the secondary partition and pass this string to the secondary partition clause.
The Merge statement is a failure, indicating that the specified secondary partition does not exist. But the partition under do exists for the table.
We use a server Oracle 11 GR 2.
Here is the code I use to fill in the data.
declare
ln_min_batchkey PLS_INTEGER;
ln_max_batchkey PLS_INTEGER;
lv_partition_name VARCHAR2 (32767).
lv_subpartition_name VARCHAR2 (32767).
Start
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
OF 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
nom_table_p = > '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
OF 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
nom_table_p = > 'STORES_COMM_MOB_SUB_INFO ',.
p_partition_name = > lv_partition_name,
p_search_string = > m2.month_val);
DBMS_OUTPUT. Put_line (' lv_subpartition_name = > ' | lv_subpartition_name |' and lv_partition_name = > ' | lv_partition_name);
IF lv_subpartition_name IS NULL
THEN
DBMS_OUTPUT. Put_line ("to the INTERIOR of FI = > ' |") 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
OF 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 (SELECT *)
OF stores_comm_mob_sub_info
SUBPARTITION (lv_subpartition_name)) T1
USING (SELECT *)
OF 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
WE (T1.store_id = T2.store_id
AND T1.ntlogin = T2.ntlogin)
WHEN MATCHED
THEN
GAME UPDATE
T1.postpaid_totalqty =
(NVL (t1.postpaid_totalqty, 0))
(+ NVL (t2.postpaid_totalqty, 0));
T1.sales_transaction_dt =
LARGEST)
NVL (t1.sales_transaction_dt,
T2.sales_transaction_dt),
NVL (t2.sales_transaction_dt,
T1.sales_transaction_dt)),
T1.batch_create_dt =
LARGEST)
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;
/
Really appreciate your input here.
Thank you
MK.Hello
You can use "immediate execution" what works.
Thank you
-
Question about the MERGE statement
Hi all
I have a small question... I can post code, table creation, etc... but I think this question can be able to be simply answered, if I explain it. If you want me to zip codes, etc... then just ask and I'll do it.
Here it goes:
I have a set up merge statement, and I have two columns. One is named ADD_DT, and the other is called LST_UPD_DT.
Update in the merge statement, the LST_UPD_DT column is updated with the SYSDATE.
When it is inserted in the merge statement, the ADD_DT column is updated with the SYSDATE.
So, here is my question:
Regardless of whether or not the information is updated, the LST_UPD_DT updates the SYSDATE every time. Any advice on how to update the LST_UPD_DT column only if information is changed/updated, so that the information is not changed would be not updated by the SYSDATE? I hope that this question was not too complicated.
Thank you all and if you want to see the code or examples of table... Please ask and I'll post one. I just thought that this may be able to meet without it.Hello
991769 wrote:
OK, here's what the table looks like:Thank you.
CREATE TABLE TBL_SUPPLIERS ( SUPP_CD VARCHAR2(40 CHAR), SUPP_NM VARCHAR2(255 CHAR), ADD_DT VARCHAR2(50 CHAR), LST_UPD_DT VARCHAR2(50 CHAR))
Do not use a VARCHAR2 column for date information. Use a DATE column.
CREATE TABLE D_SUPPLIERS ( SUPP_CD VARCHAR2(40 CHAR), SUPP_NM VARCHAR2(255 CHAR))
INSERT INTO TBL_SUPPLIERS VALUES (1234, MINING, '03-26-2013 3:33:49 PM', '04-02-2013 9:04:52 AM'); INSERT INTO TBL_SUPPLIERS VALUES (2345, ELECTRIC, '03-26-2013 3:33:49 PM', '04-02-2013 9:04:52 AM'); INSERT INTO TBL_SUPPLIERS VALUES (3456, COAL, '03-26-2013 3:33:49 PM', '04-02-2013 9:04:52 AM');
You want people to view the solutions that actually work? Please make sure that your own instructions will actually work. Test and fix your code before posting.
All INSERT statements you posted fail; You seem to be missing single quotes around string literals. I think you meant:INSERT INTO TBL_SUPPLIERS VALUES (1234, 'MINING', '03-26-2013 3:33:49 PM', '04-02-2013 9:04:52 AM'); ...
Here's one way:
MERGE INTO tbl_suppliers sm USING ( SELECT d.* FROM d_suppliers d LEFT OUTER JOIN tbl_suppliers t ON t.supp_cd = d.supp_cd WHERE t.supp_cd IS NULL OR DECODE (t.supp_nm, d.supp_nm, 0, 1) = 1 ) ds ON (sm.supp_cd = ds.supp_cd) WHEN MATCHED THEN UPDATE SET sm.supp_nm = ds.supp_nm, sm.lst_upd_dt = SYSDATE WHEN NOT MATCHED THEN INSERT (sm.supp_cd, sm.supp_nm, sm.add_dt) VALUES (ds.supp_cd, ds.supp_nm, SYSDATE); SELECT * FROM tbl_suppliers ORDER BY SUPP_CD;
This can be more efficient, because it does not generate redo, or triggers, when two tables have exactly the same line.
-
Merge statement: update only when a difference
Hello
I have two tables have almost the same columns, how can I use the merge statement to update the table target only when there is difference between the source and target table. Is there an easier way to do not compare every column one by one? I use Oracle 11.2.
Here's the MERGE statement:
Merge into trgt tb_trgt using tb_src src
on (src.id = trgt.id)
When not matched then values of insertion (trgt.id, trgt.nm, trgt.addr) (src.id, src.nm, src.nm)
when matched, then update set trgt.nm = src.nm, trgt.addr = src.addr
where trgt.nm <>src.nm or trgt.addr <>src.addr
;
Is there an easier way to clarify the clause in the NO MATCHED? I don't want to compare every column in the tables. Because I might have a lot of columns in tables.
Thank you939569 wrote:
I have two tables have almost the same columns, how can I use the merge statement to update the table target only when there is difference between the source and target table. Is there an easier way to do not compare every column one by one? I use Oracle 11.2.
Is there an easier way to clarify the clause in the NO MATCHED? I don't want to compare every column in the tables. Because I might have a lot of columns in tables.I use the method of Tom Kyte to compare tables; It gives me the differences between the source and the target using GROUP BY, who manages the value NULL comparisons. Can I use this result in the MERGER. Here is a step by step illustration. First, set up test data:
define num_rows = 10 / define pct = 20 / define value_length = 50 / define num_mods = round((&num_rows/3)*(&pct/100),0) / DROP TABLE T_TARGET; / DROP TABLE T_SOURCE; / create table t_target(key1 number, value1 varchar2(&value_length), constraint pk_target primary key(key1)); insert /*+ append */ into t_target select level+&num_mods*3, rpad('DO NOTHING - same in source and target ',&value_length, '*') from dual where level <= &num_rows-&num_mods*2 connect by level <= &num_rows-&num_mods*2; / create table t_source as select * from t_target; / insert into t_source select level, rpad('INSERT - in source, not in target ',&value_length, '*') from dual where level <= &num_mods connect by level <= &num_mods; / insert into t_target select level+&num_mods, rpad('DELETE (after update) - not in source, in target ',&value_length, '*') from dual where level <= &num_mods connect by level <= &num_mods; / insert into t_source select level+&num_mods*2, rpad('UPDATE - put this in target ',&value_length, '*') from dual where level <= &num_mods connect by level <= &num_mods; / insert into t_target select level+&num_mods*2, rpad('UPDATE - update this from source ',&value_length, '*') from dual where level <= &num_mods connect by level <= &num_mods; / commit; / select 't_target', count(*), value1 from t_target group by 't_target', value1 union all select 't_source', count(*), value1 from t_source group by 't_source', value1; / 'T_TARGET' COUNT(*) VALUE1 ---------- ---------- -------------------------------------------------- t_target 1 UPDATE - update this from source ***************** t_target 8 DO NOTHING - same in source and target *********** t_target 1 DELETE (after update) - not in source, in target * t_source 1 UPDATE - put this in target ********************** t_source 8 DO NOTHING - same in source and target *********** t_source 1 INSERT - in source, not in target ****************
So, I need to do an insert, update, and a delete.
Now I'll build code comparison step by step. I don't show the results every time, but if you run each query yourself can see what is happening.
-- Step by step build of "refresh by merge" USING ROWIDs -- Result: with cardinality hint, can use "BY USER ROWID" and avoid 3d full scan -- 1) Full scan of both tables to get data, -- identify old / new records and get old ROWID select KEY1,VALUE1, 1 old_cnt, 0 new_cnt, rowid rid from T_TARGET o UNION ALL SELECT KEY1,VALUE1, 0 old_cnt, 1 new_cnt, NULL FROM T_SOURCE n / -- 2) GROUP BY compares records, identical records have old_cnt = new_cnt select KEY1,VALUE1, sum(old_cnt) old_cnt, sum(new_cnt) new_cnt, max(rid) rid FROM ( select KEY1,VALUE1, 1 old_cnt, 0 new_cnt, rowid rid from T_TARGET o UNION ALL SELECT KEY1,VALUE1, 0 old_cnt, 1 new_cnt, NULL FROM T_SOURCE n ) group by KEY1,VALUE1 / -- 3) Filter out identical records select KEY1,VALUE1, sum(old_cnt) old_cnt, sum(new_cnt) new_cnt, max(rid) rid FROM ( select KEY1,VALUE1, 1 old_cnt, 0 new_cnt, rowid rid from T_TARGET o UNION ALL SELECT KEY1,VALUE1, 0 old_cnt, 1 new_cnt, NULL FROM T_SOURCE n ) group by KEY1,VALUE1 having sum(old_cnt) <> sum(new_cnt) / -- 4) for INSERT, keep NEW; for DELETE, keep OLD; -- for UPDATE, keep NEW values and OLD rid SELECT /*+ cardinality(1) */ KEY1,VALUE1, old_cnt, new_cnt, row_number() OVER(PARTITION BY KEY1 ORDER BY old_cnt) rn , max(rid) over(partition by key1) rid from ( select KEY1,VALUE1, sum(old_cnt) old_cnt, sum(new_cnt) new_cnt, max(rid) rid FROM ( select KEY1,VALUE1, 1 old_cnt, 0 new_cnt, rowid rid from T_TARGET o UNION ALL SELECT KEY1,VALUE1, 0 old_cnt, 1 new_cnt, NULL FROM T_SOURCE n ) group by KEY1,VALUE1 having sum(old_cnt) <> sum(new_cnt) ) / -- 5) Filter out OLD UPDATE record, not needed SELECT KEY1,VALUE1, new_cnt, rid FROM ( SELECT /*+ cardinality(1) */ KEY1,VALUE1, old_cnt, new_cnt, row_number() OVER(PARTITION BY KEY1 ORDER BY old_cnt) rn , max(rid) over(partition by key1) rid from ( select KEY1,VALUE1, sum(old_cnt) old_cnt, sum(new_cnt) new_cnt, max(rid) rid FROM ( select KEY1,VALUE1, 1 old_cnt, 0 new_cnt, rowid rid from T_TARGET o UNION ALL SELECT KEY1,VALUE1, 0 old_cnt, 1 new_cnt, NULL FROM T_SOURCE n ) group by KEY1,VALUE1 having sum(old_cnt) <> sum(new_cnt) ) ) where rn = 1 / KEY1 VALUE1 NEW_CNT RID 1 INSERT - in source, not in target **************** 1 2 DELETE (after update) - not in source, in target * 0 AAAcDHAAMAAAACtAAA 3 UPDATE - put this in target ********************** 1 AAAcDHAAMAAAACtAAB
Now, here's the real MERGER:
merge into T_TARGET o USING ( SELECT KEY1,VALUE1, new_cnt, rid FROM ( SELECT /*+ cardinality(1) */ KEY1,VALUE1, old_cnt, new_cnt, row_number() OVER(PARTITION BY KEY1 ORDER BY old_cnt) rn , max(rid) over(partition by key1) rid from ( select KEY1,VALUE1, sum(old_cnt) old_cnt, sum(new_cnt) new_cnt, max(rid) rid FROM ( select KEY1,VALUE1, 1 old_cnt, 0 new_cnt, rowid rid from T_TARGET o UNION ALL SELECT KEY1,VALUE1, 0 old_cnt, 1 new_cnt, NULL FROM T_SOURCE n ) group by KEY1,VALUE1 having sum(old_cnt) <> sum(new_cnt) ) ) where rn = 1 ) n on (o.rowid = n.rid) when matched then update set VALUE1=n.VALUE1 DELETE WHERE (n.new_cnt = 0) WHEN NOT MATCHED THEN INSERT ( KEY1,VALUE1 ) VALUES ( n.KEY1,n.VALUE1 ) /
Published by: stew Ashton on February 7, 2013 20:42
-
MERGE statement and conditional insertions
Hello
With the help of 11.2.0.3 and have merge statement
want to use
When not matched and table.colvalue is not null
then insert
but doesn't like it.
A way to insert only if some attriburte is filled.
ThnaksA way to insert only if some attriburte is filled.
insert into table_name select stmts
Merge to refer to this
http://docs.Oracle.com/CD/B19306_01/server.102/b14200/statements_9016.htm
-
Peformance tuning of merge statement
Hello
I have a merge statement that spans hours(10-12). V$ session_longops shows that he's working on the hash join, but the wait event is db file sequential read.
The art_base table has approximately 53131553 records and the x_source of the table around 3800000 records.MERGE INTO art_base ab USING x_SOURCE x ON (ab.art_no = x.art_no AND ab.sto_no = x.sto_no AND ab.yw = x.yw) WHEN MATCHED THEN UPDATE SET ab.art_qty_sale_tot = x.art_qty_sale_tot, ab.art_qty_sale_cust = x.art_qty_sale_cust, ab.src_id = 'DW', ab.bu_type_sto = x.bu_type_sto WHERE ( NVL (ab.art_qty_sale_tot, 0) <> NVL (x.art_qty_sale_tot, 0) OR NVL (ab.art_qty_sale_cust, 0) <> NVL (x.art_qty_sale_cust, 0) OR NVL (ab.bu_type_sto, 0) <> NVL (x.bu_type_sto, 0) ) WHEN NOT MATCHED THEN INSERT (ab.art_no, ab.sto_no, ab.yw, ab.art_qty_sale_tot, ab.art_qty_sale_cust, ab.src_id, ab.bu_type_sto) VALUES (x.art_no, x.sto_no, x.yw, x.art_qty_sale_tot, x.art_qty_sale_cust, 'DW', x.bu_type_sto)
There is a unique index on the table art_base art_no, sto_no, yw.
the plan
Any suggestions on how to improve performance?------------------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------------ | 0 | MERGE STATEMENT | | 3896K| 620M| | 182K (1)| 00:36:25 | | 1 | MERGE | ART_BASE | | | | | | | 2 | VIEW | | | | | | | |* 3 | HASH JOIN OUTER | | 3896K| 222M| 144M| 182K (1)| 00:36:25 | | 4 | TABLE ACCESS FULL| X_SOURCE | 3896K| 100M| | 3829 (2)| 00:00:46 | | 5 | TABLE ACCESS FULL| ART_BASE | 53M| 1672M| | 57381 (2)| 00:11:29 | ------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("ASS"."YW"(+)="X"."YW" AND "ASS"."STO_NO"(+)="X"."STO_NO" AND "ASS"."ART_NO"(+)="X"."ART_NO")
Version: 10.2.0.4
Concerning
Ankit
Published by: Ankit Goel on January 11, 2011 15:47The execution plan sounds perfect for me.
You need all THE lines of the two huge tables. There is no join faster full scan and HASH join.
Test only withselect count(*) from art_base ab INNER JOIN on x_SOURCE x ON (ab.art_no = x.art_no AND ab.sto_no = x.sto_no AND ab.yw = x.yw);
This should be 'fast enough' (minutes) and have the same (similar) execution plan. Right?
If no index help for this join.
But, perhaps that it hurts for UPDATE and INSERT?
Index of how many do you have? All BITMAP index... they can kill performance for updates on these areas.
If you have need of these indexes (for other queries) to disable THEM and rebuild them after MERGER. This merger does not run faster with any clue.V$ session_longops shows that he's working on the hash join, but the wait event is db file sequential read.
You see just LONG OPS in v$ session_longops ;-)
That will mean a COMPLETE analysis, kinds of wholesale, hash joins are LONG OPS by definition. The unique updates you do INSERT are not... you can check if the table expands revealing itself INSERTS are already works, by checking the size of the array in DBA_SEGMENTS.-andy
-
VLD-2761: impossible to generate the merge statement
Hi pros,.
I received this warning from validation on my complex mapping:
"Merge statement cannot be generated because the SUPPCODE column is used for correspondence and updating. A column cannot be updated in a merge statement.
I think that happens because of the restraint newly added to the target table that is used in my map, but what exactly does that mean?This means that the column THAT SUPPCODE is used as a correspondent and update.
Click on SUPPCODE and check the attribute propertyLoad when updating column lines = Yes
Matches columns when updating rows = YesSo the merger will not be generated for this
(The answer is mark as correct if it's useful)
See you soon
KatiaPublished by: Katia on April 28, 2010 06:13
-
Problem in the Merge statement
Hi all
I use the merge updated statement 30000 records of tables having 55 records of Lakes.
But it takes a lot of time as I kill the session after 12 hours, as it was still ongoing.
So, the same day I m using cursors, it will end in less than 3 hours.
I used merge is: -.
MERGE IN Table1 a
USING (SELECT MAX (TO_DATE (TO_CHAR (contact_date, "dd/mm/yyyy")
|| contact_time,
"jj/mm/aaaa HH24:Mi:SS".
)
) m_condate,.
appl_id
FROM Table2 b,.
(SELECT DISTINCT acc_no acc_no
IN table 3, Table1
WHERE acc_no = appl_id AND delinquent_flag = 'Y '.
AND financier_id = 'NEWACLOS') d
WHERE d.acc_no = b.appl_id
AND (contacted_by IS NOT NULL
OR followup_branch_code IS NOT NULL
)
GROUP BY appl_id) c
WE (a.appl_id = c.appl_id AND a.delinquent_flag = 'Y')
WHEN MATCHED THEN
UPDATE
SET last_contact_date = c.m_condate;
In this query, table 1 has 30000 documents and table 2 and table 3 have records 3670955 and 555674 respectively.
Please suggest, what I'm doing wrong with merger, because according to my understanding merge statement is much better than the updates or updates using cursors.
Required info is as follows:
SQL > show the user_dump_dest parameter
VALUE OF TYPE NAME
------------------------------------ ----------- ------------------------------
user_dump_dest string/opt/oracle/admin/FINCLUAT/udu
MP
SQL > show parameter optimizer
VALUE OF TYPE NAME
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling integer 2
optimizer_features_enable string 10.2.0.4
optimizer_index_caching integer 0
OPTIMIZER_INDEX_COST_ADJ integer 100
the string ALL_ROWS optimizer_mode
optimizer_secure_view_merging Boolean TRUE
SQL > show parameter db_file_multi
VALUE OF TYPE NAME
------------------------------------ ----------- ------------------------------
db_file_multiblock_read_count integer 16
SQL > show parameter db_block_size
VALUE OF TYPE NAME
------------------------------------ ----------- ------------------------------
Whole DB_BLOCK_SIZE 8192
SQL > column sname format a20
SQL > column pname format a20
SQL > column pval2 format a20
SQL > select
2 sname,
3 pname,
pval1 4,.
5 pval2
6 of
7 sys.aux_stats$;
sys.aux_stats$
*
ERROR on line 7:
ORA-00942: table or view does not exist
Elapsed time: 00:00:00.05
SQL > explain the plan for
2 - Put your statement here
3 MERGE IN one cs_case_info
4 USE (SELECT MAX (TO_DATE (TO_CHAR (contact_date, "dd/mm/yyyy")
5 || contact_time,
6 'dd/mm/yyyy HH24:Mi:SS.
7 )
(8) m_condate,
9 appl_id
CS_CASE_DETAILS_ACLOS 10 b,
11 (SELECT DISTINCT acc_no acc_no
12 OF NEWACLOS_RESEARCH_HIST_AYLA, cs_case_info
13 WHERE acc_no = appl_id AND delinquent_flag = 'Y '.
14 AND financier_id = "NEWACLOS") d
15 WHERE d.acc_no = b.appl_id
16 AND (contacted_by IS NOT NULL
17 GOLD followup_branch_code IS NOT NULL
18 )
C 19 GROUP BY appl_id)
20. WE (a.appl_id = c.appl_id AND a.delinquent_flag = 'Y')
21. WHEN MATCHED THEN
UPDATE 22
23 SET last_contact_date = c.m_condate
24;
He explained.
Elapsed time: 00:00:00.08
SQL > select * from table (dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
| ID | Operation | Name | Lines | Bytes | TempSpc | Cost (% CPU).
--------------------------------------------------------------------------------------------------
| 2 > MERGE STATEMENT | 47156 | 874K | 128K (1) |
| 1. MERGE | CS_CASE_INFO |
| 2. VIEW |
| 3. HASH JOIN | 47156 | 36 M | 5672K | 128K (1) |
| 4. VIEW | 47156 | 5111K | 82339 (1) |
| 5. GROUP SORT BY | 47156 | 4236K | 298 M | 82339 (1) |
| 6. HASH JOIN | 2820K | 247 M | 10 M | 60621 (1) |
| 7. HASH JOIN | 216K | 7830K | 6985 (1) |
| 8. VIEW | the index $ _join$ _012 | 11033. 258K | 1583 (1) |
| 9. HASH JOIN |
| 10. INDEX RANGE SCAN | IDX_CCI_DEL | 11033. 258K | 768 (1) |
| 11. INDEX RANGE SCAN | CS_CASE_INFO_UK | 11033. 258K | 821 (1) |
| 12. FULL RESTRICTED INDEX SCAN FAST | IDX_NACL_RSH_ACC_NO | 5539K | 68 M | 5382 (1) |
| 13. TABLE ACCESS FULL | CS_CASE_DETAILS_ACLOS | 3670K | 192 M | 41477 (1) |
| 14. TABLE ACCESS FULL | CS_CASE_INFO | 304K | 205 M | 35975 (1) |
--------------------------------------------------------------------------------------------------
Note
-----
-"PLAN_TABLE' is old version
24 selected lines.
Elapsed time: 00:00:01.04
SQL > rollback;
Complete restoration.
Elapsed time: 00:00:00.03
SQL > set autotrace traceonly arraysize 100
SQL > alter session set events 10046 name context forever, trace level 8';
ERROR:
ORA-01031: insufficient privileges
Elapsed time: 00:00:00.04
SQL > disconnect
Disconnected from the database to Oracle 10 g Enterprise Edition Release 10.2.0.4.0 - Production 64-bit
With partitioning, OLAP, Data Mining and Real Application Testing options
SQL > spool off
Published by: user4528984 on May 5, 2009 22:37Create indexes for tables. CS_CASE_DETAILS_ACLOS, CS_CASE_INFO
also try to use the underside of suspicion
(SELECT / * + no_merge * / SEPARATE acc_no acc_no)
IN table 3, Table1HTH
Maybe you are looking for
-
BOOTMGR not found - cannot start Windows
I have a similar problem... Start the computer and I get:-BOOTMGR not found... Press Ctrl + Alt + Del I put the Toshiba recovery disc in and it registered no operating system... I finally gave up and removed the completely hardrive and tried to insta
-
Defines a point in a discreet XY Chart. (Correction curve)
I have an XY graph, which consists of discrete points. As X Y 100 1.2 150 2.3 200 1.5 2 250 300 1.8 This is usually used as a correction curve, which shows a tendency to a value of Y for a specific X. OK, I have an X, but not in the XY graph p
-
HelloI remove someone by chance how I can restore the new contact
-
I have thhink the question says it all. On my previous PC, when I scanned a page, it asks if you want another scan and if you did, they would all wind upward in the same folder?
-
Hi, I work on a PC with windows 7, first cc 2015.4Today, I installed red giant universe. Some features did not work and gave me an error that it cannot find al sorts different image files.now I try not to use any od red giant plugins and I still get