Silently drop the test table
declare
no_table exception;
pragma Exception_Init (no_table, -00942);
begin
execute immediate 'drop table ero_tst';
exception
when no_table
then
null;
end;
/
Table dropped.
Create table
create table ero_tst
as
select level id
, cast (null as varchar2(30)) txt
from dual
connect by level <= 10
Table created.
List data
select *
from ero_tst
order by id
Merge statement without problems
declare
eol constant varchar2(1) := chr(10);
stmnt clob;
begin
stmnt := 'merge /*+ WITH_PLSQL */' ||eol||
'into ero_tst tgt' ||eol||
'using (' ||eol||
' with' ||eol||
' function update_text' ||eol||
' return varchar2' ||eol||
' is' ||eol||
' begin' ||eol||
' return (''updated'');' ||eol||
' end update_text;' ||eol||
'' ||eol||
' select level upd_id' ||eol||
' , update_text update_text' ||eol||
' from dual' ||eol||
' where mod(level,2) = 0' ||eol||
' connect by level <= 10' ||eol||
' ) src' ||eol||
'on (tgt.id = src.upd_id' ||eol||
' )' ||eol||
'when matched' ||eol||
'then' ||eol||
' update' ||eol||
' set tgt.txt = src.update_text'
;
execute immediate stmnt
;
dbms_output.put_line ('Numer of records merged: '||to_char(sql%rowcount,'fm999g999g999'));
commit;
end;
Numer of records merged: 5
List data
select *
from ero_tst
order by id
ID | TXT | 1 | - | 2 | updated | 3 | - | 4 | updated | 5 | - | 6 | updated | 7 | - | 8 | updated | 9 | - | 10 | updated |
---|
Problematic merge
declare
eol constant varchar2(1) := chr(10);
stmnt clob;
begin
-- to make this a problem merge statement activate the where-line with the bind variable
-- (and obviously deactivate the where-line without), and activate the using-clause at the
-- execute immediate
-- ORACLE WILL PROBABLY NOT BE HAPPY IF YOU THIS ON LIVESQL.
-- IF YOU DO THIS AT WORK, YOUR DBA MAY CALL AND ASK WHY YOU'RE CAUSING
-- ACCESS VIOLATION MESSAGES IN THE ALERT LOG
stmnt := 'merge /*+ WITH_PLSQL */' ||eol||
'into ero_tst tgt' ||eol||
'using (' ||eol||
' with' ||eol||
' function update_text' ||eol||
' return varchar2' ||eol||
' is' ||eol||
' begin' ||eol||
' return (''updated'');' ||eol||
' end update_text;' ||eol||
'' ||eol||
' select level upd_id' ||eol||
' , update_text update_text' ||eol||
' from dual' ||eol||
-- ' where mod(level,:A) = 0' ||eol|| -- replace next line with this line and uncomment
' where mod(level,2) = 0' ||eol||
' connect by level <= 10' ||eol||
' ) src' ||eol||
'on (tgt.id = src.upd_id' ||eol||
' )' ||eol||
'when matched' ||eol||
'then' ||eol||
' update' ||eol||
' set tgt.txt = src.update_text'
;
execute immediate stmnt
-- using 2 --uncomment
;
dbms_output.put_line ('Numer of records merged: '||to_char(sql%rowcount,'fm999g999g999'));
end;
Numer of records merged: 5
List data
select *
from ero_tst
order by id
ID | TXT | 1 | - | 2 | updated | 3 | - | 4 | updated | 5 | - | 6 | updated | 7 | - | 8 | updated | 9 | - | 10 | updated |
---|