使用动态 SQL 以 table 名称作为输入的 Oracle SQL 过程
Oracle SQL procedure with table name as input using dynamic SQL
我看到很多类似的问题已经得到解答,包括 here, here and here。清单还在继续。
是什么让我的与众不同?其他这些问题看似很简单,一行sql语句。我有一个更复杂的跨越多行的合并语句,无论我如何尝试将语句放在一起,它都会给我一个编译错误。下面是一个这样的尝试。
这是一个很长的语句,唯一的动态部分是开头的2个不连续的行,如下所示。我试图将整个语句变成一个字符串并执行它,但是我得到一个错误,提示字符串太长,而且这使得它很难阅读,所以这是不可取的。我还尝试将需要动态 sql 的 2 个部分分解为 2 个立即执行块,但这也会引发编译错误。
我的代码
create or replace procedure table_sync(
table_name in varchar2,
source_node in varchar2
)
is
begin
execute immediate
'merge into ' || table_name || ' dest' /* ---- first line ---- */
using (select date_time, version_date, data_entry_date, value
'from username.' || table_name || '@' || source_node /* ---- second line ---- */
where data_entry_date < (sysdate - 10)) src
on ( dest.date_time = src.date_time and
dest.version_date = src.version_date
)
when matched then
update
set
dest.data_entry_date = src.data_entry_date,
dest.value = src.value
where
(case
.
.
.
有没有办法合并这个动态语句?
谢谢
使用合并来实现这是一个很好的方法,但是您的语句缺少一些引号。这是一个 fiddle 示例,类似于您正在尝试做的事情。
根据 fiddle,创建测试数据:
create table table1(id varchar2(30), username varchar2(30), fullname varchar2(30));
create table table2(id varchar2(30), username varchar2(30), fullname varchar2(30));
insert into table1 values('a1', 'b1', 'c1');
insert into table1 values('a2', 'b2', 'c2');
insert into table1 values('a3', 'b3', 'c3');
insert into table1 values('a4', 'b4', 'c4');
insert into table2 values('a1', 'b1', 'c1');
insert into table2 values('a2', 'b2', 'c2');
insert into table2 values('a3', 'b3', 'c3');
你的函数:
CREATE OR replace PROCEDURE Table_sync(table_name IN VARCHAR2)
IS
stmnt CLOB;
BEGIN
stmnt := 'merge into ' || table_name || ' dest '
|| 'using (select id, username from table1) src '
|| 'on (dest.id = src.id) '
||
' when matched then update set dest.fullname = src.username || src.id '
|| ' where dest.username like ''%2'' '
|| ' when not matched then insert (id, username, fullname) values(src.id, src.id||src.username, src.username||src.username) '
;
EXECUTE IMMEDIATE stmnt;
END table_sync;
如果table1中col1中的记录与table2中的列具有相同的值,那么它会根据条件更新它,如果记录不存在,它会插入它。
您可以在 where 语句中写下所有条件,并注意动态查询中用于引用值的 2 个单引号。
我看到很多类似的问题已经得到解答,包括 here, here and here。清单还在继续。
是什么让我的与众不同?其他这些问题看似很简单,一行sql语句。我有一个更复杂的跨越多行的合并语句,无论我如何尝试将语句放在一起,它都会给我一个编译错误。下面是一个这样的尝试。
这是一个很长的语句,唯一的动态部分是开头的2个不连续的行,如下所示。我试图将整个语句变成一个字符串并执行它,但是我得到一个错误,提示字符串太长,而且这使得它很难阅读,所以这是不可取的。我还尝试将需要动态 sql 的 2 个部分分解为 2 个立即执行块,但这也会引发编译错误。
我的代码
create or replace procedure table_sync(
table_name in varchar2,
source_node in varchar2
)
is
begin
execute immediate
'merge into ' || table_name || ' dest' /* ---- first line ---- */
using (select date_time, version_date, data_entry_date, value
'from username.' || table_name || '@' || source_node /* ---- second line ---- */
where data_entry_date < (sysdate - 10)) src
on ( dest.date_time = src.date_time and
dest.version_date = src.version_date
)
when matched then
update
set
dest.data_entry_date = src.data_entry_date,
dest.value = src.value
where
(case
.
.
.
有没有办法合并这个动态语句?
谢谢
使用合并来实现这是一个很好的方法,但是您的语句缺少一些引号。这是一个 fiddle 示例,类似于您正在尝试做的事情。
根据 fiddle,创建测试数据:
create table table1(id varchar2(30), username varchar2(30), fullname varchar2(30));
create table table2(id varchar2(30), username varchar2(30), fullname varchar2(30));
insert into table1 values('a1', 'b1', 'c1');
insert into table1 values('a2', 'b2', 'c2');
insert into table1 values('a3', 'b3', 'c3');
insert into table1 values('a4', 'b4', 'c4');
insert into table2 values('a1', 'b1', 'c1');
insert into table2 values('a2', 'b2', 'c2');
insert into table2 values('a3', 'b3', 'c3');
你的函数:
CREATE OR replace PROCEDURE Table_sync(table_name IN VARCHAR2)
IS
stmnt CLOB;
BEGIN
stmnt := 'merge into ' || table_name || ' dest '
|| 'using (select id, username from table1) src '
|| 'on (dest.id = src.id) '
||
' when matched then update set dest.fullname = src.username || src.id '
|| ' where dest.username like ''%2'' '
|| ' when not matched then insert (id, username, fullname) values(src.id, src.id||src.username, src.username||src.username) '
;
EXECUTE IMMEDIATE stmnt;
END table_sync;
如果table1中col1中的记录与table2中的列具有相同的值,那么它会根据条件更新它,如果记录不存在,它会插入它。
您可以在 where 语句中写下所有条件,并注意动态查询中用于引用值的 2 个单引号。