使用动态SQL输入表名作为Oracle SQL过程

问题描述 投票:0回答:1

[我看到已经回答了很多类似的问题,包括hereherehere。列表继续。

什么使我与众不同?这些其他问题似乎非常简单,只有一行sql语句。我有一个更复杂的merge语句,它跨越多行,无论我如何尝试将该语句放在一起,它都会给我带来编译错误。下面是一种这样的尝试。

这是一个很长的语句,唯一的动态部分在开始时是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 
                          .
                          .
                          .

是否有办法组合此动态语句?

谢谢

sql oracle stored-procedures dynamic-sql
1个回答
0
投票

使用合并来实现这一点是一种很好的方法,但是您的语句缺少一些引号。这是带有示例的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 :1 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 using table_name;
END table_sync;

如果表1中的记录在col1中与表2中的列具有相同的值,那么它将根据条件进行更新,如果该记录不存在,则将其插入。

您可以在where语句中编写所有条件,并注意用于在动态查询中引用值的2x单引号。

© www.soinside.com 2019 - 2024. All rights reserved.