ORACLE - Динамический Sql с использованием CLOB

У меня есть таблица, как описано ниже

SQL> desc tab_script
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 SRLNO                                              NUMBER
 INSERT_SCRIPT                                      CLOB

insert_script заполняется оператором вставки. Я хочу выполнить скрипт вставки динамически. Я написал следующий код, но не работает.

DECLARE
  ln_type_id NUMBER:= 1;
  lcl_sql    clob;
BEGIN
 FOR rec IN ( SELECT * FROM tab_script )
 LOOP
   lcl_sql:= rec.insert_script;
   EXECUTE IMMEDIATE lcl_sql ;
 END LOOP;
 COMMIT;
END;

Моя оракул версия Oracle Database 11g Enterprise Edition, выпуск 11.2.0.4.0 - 64-разрядная версия

2 ответа

1. Всегда рекомендуется печатать SQL-запрос, используя dbms_output.put_line и проверить SQL,

2. В случае, если у вас есть несколько insert заявления, то вы можете использовать BEGIN а также END

DECLARE
v_sql CLOB;
BEGIN
For i in (select * from tab_script)
LOOP
v_sql:= i.insert_script ;
-- Use below line ony if you have multiple insert statements seperated with semi-column
--v_sql := ' BEGIN ' || v_sql || ' END; ' ; 
 dbms_output.put_line('SQL STMNT - ' || v_sql); -- This is to check SQL 
execute immediate  v_sql ;
commit;
END LOOP;
EXCEPTION 
WHEN OTHERS 
THEN 
--dbms_output.put_line('' ); 
--Calling procedure to log/insert the exceptions, if any
LOG_PROC_ERRORS('Error with statement :  ' || v_sql ||
 ' ' || ' Error message : ' || ' ' || sqlerrm || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE ); 
END;

Выход:

SQL STMNT - insert into emp(ID,NAME) values(7,'KLM');

ЖУРНАЛ ОШИБОК

Я полагаю, вы сохранили несколько вставок в столбце clob, верно? Но EXECUTE IMMEDIATE работает только с одной операцией за цикл:

CREATE TABLE TEST(ID INTEGER, NAME VARCHAR2(50));

BEGIN
   EXECUTE IMMEDIATE 'insert into test (id, name) values (1, ''first'')'; 
   EXECUTE IMMEDIATE 'insert into test (id, name) values (2, ''second'')'; 
--   EXECUTE IMMEDIATE 'insert into test (id, name) values (3, ''third'');insert into test (id, name) values (4, ''fourth'');'; 
   COMMIT;
END;
/

SELECT * FROM TEST;

DROP TABLE TEST;

В приведенном выше примере все работает отлично, и результат, как и ожидалось:

ID  NAME    
1   first
2   second

Но если вы раскомментируете третий EXECUTE-IMMEDIATE, выдается ошибка.

Если это ваша проблема, вам придется разделить свои INPUT-операторы в точке с запятой и выполнять каждое из них.

Другие вопросы по тегам