Как вставить многострочный результат динамического SQL в другую таблицу? - PullRequest
0 голосов
/ 03 мая 2019

Я пишу один динамический SQL, результатом которого является таблица с 2 столбцами и несколькими строками, я хочу вставить его в другую таблицу с 4 столбцами, 2 из которых будут заполнены результатом динамического SQL, я пытаюсь использовать коллекцию, но не знаю, как вставить результат в другую таблицу

CREATE OR REPLACE PROCEDURE P_C_SM_Failure_error_Code_P2P AS

v_month          VARCHAR2(16); -- to get Month for each table
v_day            VARCHAR2(16); -- to get day for each table
v_ERRCODE        t_c_rpt_resultmsg.code%TYPE;
v_ERRMSG         t_c_rpt_resultmsg.MESSAGE%TYPE;
v_param          VARCHAR2(16);
v_sql            VARCHAR2(3000);
v_result         number;
type t_c_result is record (Err_code varchar2(2000), Err_count number);
type v_t_result is table of t_c_result index by PLS_INTEGER;
v_t1_result      v_t_result; 
BEGIN
v_sql :='0';
v_param := 'Gateway_G';
v_result := '0';
select to_char(sysdate - 1,'MM') into v_month from dual;
select to_char(sysdate - 1,'DD') into v_day from dual;

-- Get count of P2P
v_sql := '(select count(*), error_code from (
select error_code from sm_histable'||v_month||''||v_day||'@ORASMSC01 where 
orgaccount = '''||v_param||''' and destaccount = '''||v_param||''' and 
sm_status <> 1 union all
select error_code from sm_histable'||v_month||''||v_day||'@ORASMSC02 where 
orgaccount = '''||v_param||''' and destaccount = '''||v_param||''' and 
sm_status <> 1 )
group by error_code)';
EXECUTE IMMEDIATE v_sql bulk collect into v_t1_result; 

--insert into t_c_rpt_result2 values (trunc(sysdate, 'DD'), v_errcount, 
v_err_code,'Failure_error_Code_P2P');


--for indx in 1 .. v_t1_result.COUNT
--loop
--dbms_output.put_line (v_t1_result (indx).Err_code);
--end loop;

Ответы [ 2 ]

0 голосов
/ 03 мая 2019

Я думаю, что вы ищете отличный вариант использования FORALL.Заполняемую вами коллекцию необходимо выполнить с помощью execute execute, поскольку вы динамически создаете имя таблицы.Но вставка в t_c_rpt_result2 выглядит для меня статичной.

BEGIN
   v_sql :=
         '(select count(*) as cnt, error_code 
           from (
               select error_code from sm_histable'
      || v_month
      || ''
      || v_day
      || '@ORASMSC01 
            where orgaccount = :x and destaccount = :x  and sm_status <> 1 
            union all
               select error_code from sm_histable'
      || v_month
      || ''
      || v_day
      || '@ORASMSC02 
            where  orgaccount = :x and destaccount = :x and sm_status <> 1 )
         group by error_code)';

   EXECUTE IMMEDIATE v_sql BULK COLLECT INTO v_t1_result USING v_param;

   FORALL indx IN 1 .. v_t1_result.COUNT
      INSERT INTO t_c_rpt_result2 (err_dt,
                                   err_msg,
                                   errcount,
                                   ERROR_CODE)
           VALUES (TRUNC (SYSDATE, 'DD'),
                   'Failure_error_Code_P2P',
                   v_t1_result (indx).cnt,
                   v_t1_result (indx).ERROR_CODE);
END;

Найдите больше примеров FORALL на LiveSQL здесь .Конечно, даже если ваша вставка была динамической, вы можете использовать FORALL - поместить немедленное выполнение непосредственно «внутри» оператора FORALL.Но я не думаю, что сложность здесь оправдана.

Надеюсь, это поможет!

0 голосов
/ 03 мая 2019

Вы можете добавить постоянные значения даты и сообщения об ошибке в подзапрос и запустить динамическую вставку.Это также должно работать, если вы удалите внешние скобки вашего динамического SQL, поскольку константы могут быть включены в group by.Всегда не забывайте передавать значения как переменные связывания, а не объединять их (v_param).Кроме того, указывайте имена столбцов явно в операторе INSERT.

v_sql := '(select count(*) as cnt, error_code 
           from (
               select error_code from sm_histable'||v_month||''||v_day||'@ORASMSC01 
            where orgaccount = :x and destaccount = :x  and sm_status <> 1 
            union all
               select error_code from sm_histable'||v_month||''||v_day||'@ORASMSC02 
            where  orgaccount = :x and destaccount = :x and sm_status <> 1 )
         group by error_code)';
EXECUTE IMMEDIATE v_sql bulk collect into v_t1_result using v_param; 

EXECUTE IMMEDIATE 'insert into t_c_rpt_result2(err_dt,err_msg,errcount,error_code) 
                    select :dt,:msg,cnt,error_code from '|| v_sql
        USING trunc(sysdate, 'DD'),'Failure_error_Code_P2P',v_param;
...