Updates Based on Queries
This article describes how a table can be updated using data from another table.
oracle miscconfigurationintermediate
by OracleDba
14 views
This article describes how a table can be updated using data from another table.
12345678910111213141516171819202122232425262728293031323334
DROP TABLE dest_tab PURGE;
DROP TABLE source_tab PURGE;
CREATE TABLE dest_tab AS
SELECT level AS id,
'CODE' || level AS code,
'Description for ' || level AS description
FROM dual
CONNECT BY level <= 10000;
ALTER TABLE dest_tab ADD CONSTRAINT dest_tab_pk PRIMARY KEY (id);
CREATE TABLE source_tab AS
SELECT level AS id,
'CODE' || (level*10) AS code,
'Updated description for ' || level AS description
FROM dual
CONNECT BY level <= 5000;
ALTER TABLE source_tab ADD CONSTRAINT source_tab_pk PRIMARY KEY (id);
EXEC DBMS_STATS.gather_table_stats(USER, 'dest_tab');
EXEC DBMS_STATS.gather_table_stats(USER, 'source_tab');
SELECT COUNT(*)
FROM dest_tab
WHERE description LIKE 'Updated%';
COUNT(*)
----------
0
SQL>1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
UPDATE dest_tab tt
SET (tt.code, tt.description) = (SELECT st.code, st.description
FROM source_tab st
WHERE st.id = tt.id)
WHERE EXISTS (SELECT 1
FROM source_tab
WHERE id = tt.id);
5000 rows updated.
SQL>
SELECT COUNT(*)
FROM dest_tab
WHERE description LIKE 'Updated%';
COUNT(*)
----------
5000
SQL>
ROLLBACK;
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 4999 | 185K| 30013 (34)| 00:06:01 |
| 1 | UPDATE | dest_tab | | | | |
| 2 | NESTED LOOPS SEMI | | 4999 | 185K| 19 (6)| 00:00:01 |
| 3 | TABLE ACCESS FULL | dest_tab | 10000 | 332K| 18 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN | source_tab_PK | 2500 | 10000 | 0 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID| source_tab | 1 | 43 | 2 (0)| 00:00:01 |
|* 6 | INDEX UNIQUE SCAN | source_tab_PK | 1 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("ID"="TT"."ID")
6 - access("ST"."ID"=:B1)
UPDATE /*+ PARALLEL(8) */ dest_tab tt
SET (tt.code, tt.description) = (SELECT st.code, st.description
FROM source_tab st
WHERE st.id = tt.id)
WHERE EXISTS (SELECT 1
FROM source_tab
WHERE id = tt.id);12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
UPDATE (SELECT tt.id,
tt.code,
tt.description,
st.code AS st_code,
st.description AS st_description
FROM dest_tab tt, source_tab st
WHERE tt.id = st.id) ilv
SET ilv.code = ilv.st_code,
ilv.description = ilv.st_description;
5000 rows updated.
SQL>
SELECT COUNT(*)
FROM dest_tab
WHERE description LIKE 'Updated%';
COUNT(*)
----------
5000
SQL>
ROLLBACK;
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 5000 | 375K| 31 (4)| 00:00:01 |
| 1 | UPDATE | dest_tab | | | | |
|* 2 | HASH JOIN | | 5000 | 375K| 31 (4)| 00:00:01 |
| 3 | TABLE ACCESS FULL| source_tab | 5000 | 209K| 12 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| dest_tab | 10000 | 332K| 18 (0)| 00:00:01 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TT"."ID"="ST"."ID")
UPDATE /*+ PARALLEL(8) */
(SELECT tt.id,
tt.code,
tt.description,
st.code AS st_code,
st.description AS st_description
FROM dest_tab tt, source_tab st
WHERE tt.id = st.id) ilv
SET ilv.code = ilv.st_code,
ilv.description = ilv.st_description;
-- Rows limited by the inline view.
UPDATE (SELECT tt.id,
tt.code,
tt.description,
st.code AS st_code,
st.description AS st_description
FROM dest_tab tt, source_tab st
WHERE tt.id = st.id
AND st.id <= 2500) ilv
SET ilv.code = ilv.st_code,
ilv.description = ilv.st_description;
-- Rows limited by the WHERE clause of the UPDATE.
UPDATE (SELECT tt.id,
tt.code,
tt.description,
st.code AS st_code,
st.description AS st_description
FROM dest_tab tt, source_tab st
WHERE tt.id = st.id) ilv
SET ilv.code = ilv.st_code,
ilv.description = ilv.st_description
WHERE ilv.id <= 2500;1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
MERGE INTO dest_tab tt
USING source_tab st
ON (tt.id = st.id)
WHEN MATCHED THEN
UPDATE SET tt.code = st.code,
tt.description = st.description;
5000 rows merged.
SQL>
SELECT COUNT(*)
FROM dest_tab
WHERE description LIKE 'Updated%';
COUNT(*)
----------
5000
SQL>
ROLLBACK;
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 5000 | 429K| 31 (4)| 00:00:01 |
| 1 | MERGE | dest_tab | | | | |
| 2 | VIEW | | | | | |
|* 3 | HASH JOIN | | 5000 | 375K| 31 (4)| 00:00:01 |
| 4 | TABLE ACCESS FULL| source_tab | 5000 | 209K| 12 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| dest_tab | 10000 | 332K| 18 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("TT"."ID"="ST"."ID")
MERGE /*+ APPEND PARALLEL(8) */ INTO dest_tab tt
USING source_tab st
ON (tt.id = st.id)
WHEN MATCHED THEN
UPDATE SET tt.code = st.code,
tt.description = st.description;
MERGE INTO dest_tab tt
USING (SELECT * FROM source_tab WHERE id <= 2500) st
ON (tt.id = st.id)
WHEN MATCHED THEN
UPDATE SET tt.code = st.code,
tt.description = st.description;Please to add comments
No comments yet. Be the first to comment!