生成merge into 脚本
背景介绍:由于单表字段数较多,生成的脚本长度超过varchar2类型存储上限,需要使用clob字段存储脚本,且Dbms_Lob.Append不能用于sql语句中,需要创建临时表处理
表命名规则:
源表tb,临时表temp_tb
结果输出到中间表test.temp_merge_sql
create table test.temp_merge_sql(
owner varchar2(128), ----表属主
table_name varchar2(128), ----表名
key_col1 varchar2(256), ----表主键
key_col2 varchar2(256), ----merge条件
part1 varchar2(4000), ----中间输出
part2 varchar2(4000), ----中间输出
ouput_sql clob, -----merge语句输出
flag char(1)); ----处理情况复制
步骤:
1、向中间表test.temp_merge_sql插入待生成脚本的表清单(插入字段owner,table_name)
Select *
From test.temp_Merge_Sql
For Update;复制
2、更新主键,merge条件
Update test.temp_Merge_Sql a
Set a.Key_Col1 =
(Select b.Pri_Key
From (Select c.Owner Owner,
a.Constraint_Name,
c.Table_Name Table_Name,
Listagg(c.Column_Name, ',') Within Group(Order By c.Position) Pri_Key
From Dba_Constraints a,
test.temp_Merge_Sql b,
Dba_Cons_Columns c
Where a.Owner = b.Owner
And a.Table_Name = b.Table_Name
And c.Owner = b.Owner
And c.Table_Name = b.Table_Name
And c.Constraint_Name = a.Constraint_Name
And a.Constraint_Type = 'P'
Group By c.Owner, a.Constraint_Name, c.Table_Name) b
Where a.Owner = b.Owner
And a.Table_Name = b.Table_Name),
a.Key_Col2 =
(Select b.Pri_Key
From (Select c.Owner Owner,
a.Constraint_Name,
c.Table_Name Table_Name,
Listagg('a.' || c.Column_Name || '=c.' ||
c.Column_Name,
' and ') Within Group(Order By c.Position) Pri_Key
From Dba_Constraints a,
test.temp_Merge_Sql b,
Dba_Cons_Columns c
Where a.Owner = b.Owner
And a.Table_Name = b.Table_Name
And c.Owner = b.Owner
And c.Table_Name = b.Table_Name
And c.Constraint_Name = a.Constraint_Name
And a.Constraint_Type = 'P'
Group By c.Owner, a.Constraint_Name, c.Table_Name) b
Where a.Owner = b.Owner
And a.Table_Name = b.Table_Name)
Where a.Flag Is Null
And a.Key_Col1 Is Null;复制
3、生成merge脚本
Declare
v_Sql Clob;
v_Part1 Varchar2(4000);
v_Part2 Varchar2(4000);
Begin
For Cur In (Select a.Owner, a.Table_Name, a.Key_Col1, a.Key_Col2
From test.temp_Merge_Sql a
Where a.Flag Is Null
And a.Key_Col1 Is Not Null
And a.Key_Col2 Is Not Null)
Loop
Dbms_Lob.Createtemporary(v_Sql, True); ----初始化clob对象
Select 'merge into ' || Cur.Owner || '.' || Cur.Table_Name ||
' a using (select * from ' || Cur.Owner || '.temp_' ||
Cur.Table_Name || ')c on (' || Cur.Key_Col2 ||
') when matched then update set ' || Listagg(a.Col, ',') Within Group(Order By Column_Id)
Into v_Part1
From (Select 'a.' || Column_Name || '=c.' || Column_Name As Col,
'a.' || Column_Name As Col2,
'c.' || Column_Name As Col3,
Column_Id,
Table_Name
From Dba_Tab_Cols
Where Table_Name = Cur.Table_Name
And Owner = Cur.Owner
And Column_Name Not In
(Select Substr(Cur.Key_Col1 || ',',
Decode(Level,
1,
0,
Instr(Cur.Key_Col1 || ',',
',',
1,
Level - 1) + 1),
Instr(Cur.Key_Col1 || ',', ',', 1, Level) -
Decode(Level,
1,
0,
Instr(Cur.Key_Col1 || ',',
',',
1,
Level - 1)) - 1)
From Dual
Connect By Level <=
Length(Cur.Key_Col1 || ',') -
Length(Replace(Cur.Key_Col1 || ',', ',', '')))
Order By Column_Id) a
Group By a.Table_Name;
Select ' when not matched then insert(' || Listagg(a.Col2, ',') Within Group(Order By Column_Id) || ') values (' || Listagg(a.Col3, ',') Within Group(Order By Column_Id) || ');'
Into v_Part2
From (Select 'a.' || Column_Name || '=c.' || Column_Name As Col,
'a.' || Column_Name As Col2,
'c.' || Column_Name As Col3,
Column_Id,
Table_Name
From Dba_Tab_Cols
Where Table_Name = Cur.Table_Name
And Owner = Cur.Owner
Order By Column_Id) a
Group By a.Table_Name;
Dbms_Lob.Append(v_Sql, v_Part1);
Dbms_Lob.Append(v_Sql, v_Part2);
Update test.temp_Merge_Sql a
Set (Part1, Part2, Ouput_Sql) =
(Select v_Part1, v_Part2, v_Sql
From Dual)
Where a.Owner = Cur.Owner
And a.Table_Name = Cur.Table_Name;
Update test.temp_Merge_Sql a
Set a.Flag = '1'
Where a.Owner = Cur.Owner
And a.Table_Name = Cur.Table_Name;
Commit;
End Loop;
End;
/复制
4、查看输出merge语句
Select *
From test.temp_Merge_Sql;复制
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
705次阅读
2025-04-18 14:18:38
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
635次阅读
2025-04-15 17:24:06
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
547次阅读
2025-04-20 10:07:02
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
495次阅读
2025-04-17 17:02:24
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
490次阅读
2025-04-22 00:20:37
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
487次阅读
2025-04-22 00:13:51
一页概览:Oracle GoldenGate
甲骨文云技术
471次阅读
2025-04-30 12:17:56
火焰图--分析复杂SQL执行计划的利器
听见风的声音
418次阅读
2025-04-17 09:30:30
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
373次阅读
2025-04-15 14:48:05
OR+DBLINK的关联SQL优化思路
布衣
360次阅读
2025-05-05 19:28:36