Oracle SQL процедура с именем таблицы в качестве ввода с использованием Dynami c SQL - PullRequest
0 голосов
/ 18 февраля 2020

Я вижу много похожих вопросов, на которые уже даны ответы, включая здесь , здесь и здесь . Список можно продолжить.

Что отличает меня? Эти другие вопросы кажутся очень простыми, в одной строке sql утверждений. У меня есть более сложный оператор слияния, который занимает несколько строк, и независимо от того, как я пытался соединить этот оператор, он вызывает ошибку компиляции. Ниже приведена одна такая попытка.

Это длинное утверждение, единственные динамические части c - это две непоследовательные строки в самом начале, как показано ниже. Я попытался сделать весь оператор строкой и выполнить его, но я получаю сообщение об ошибке, что строка слишком длинная, плюс это делает его очень трудным для чтения, поэтому это нежелательно. Я также попытался разбить 2 части, которые требуют динамического c sql, на 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 
                          .
                          .
                          .

Есть ли способ объединить эту динамическую c инструкцию?

Спасибо

1 Ответ

0 голосов
/ 18 февраля 2020

Использование слияния для достижения этой цели является хорошим подходом, но в вашем утверждении отсутствуют некоторые кавычки. Вот скрипка с примером, аналогичным тому, что вы пытаетесь сделать.

Из этой скрипки создайте тестовые данные:

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;

Если запись в таблице1 существует с тем же значением в столбце col1, что и столбец в таблице2, то она обновит ее на основе условия, если запись не существует, она вставит ее.

Вы можете написать все свои условия внутри оператора where и обратить внимание на двойные кавычки, используемые для цитирования значений в динамическом запросе c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...