【问题标题】:ORACLE - Dynamic Sql using CLOBORACLE - 使用 CLOB 的动态 Sql
【发布时间】:2016-04-20 14:35:35
【问题描述】:

我有一张如下所述的表格

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 企业版 11.2.0.4.0 - 64 位生产

【问题讨论】:

  • 不起作用”既不是有效的 Oracle 错误消息,也不是可接受的问题描述。
  • 能否请您也发布错误?

标签: oracle plsql dynamic-sql clob


【解决方案1】:

1.使用dbms_output.put_line 打印SQL 查询并验证SQL 始终是一个好习惯。

2.如果您有多个insert 语句,则可以使用BEGINEND

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');

【讨论】:

    【解决方案2】:

    我猜,你已经在你的 clob-column 中存储了多个 INSERT,对吧? 但 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-Statements 并逐个执行。

    【讨论】:

    • Execute immediate 可用于执行多个使用BEGINEND 的语句,见上例。
    • 我诚挚的歉意.. 我的插入语句在 sql 或动态 sql 中执行时抛出错误。
    • 我的插入语句在 toad 中执行时执行良好。在 sqlplus 或 pl/sql 中执行时失败。原因是格式..
    • null,null,null,null,null,null,null,to_date('', 'dd/mm/rrrr hh24:mi:ss'),to_date('', 'dd/mm /rrrr hh24:mi:ss'),'E','GHPLPAS',to_date('06/03/2009 00:00:00',
    • sqlplus 和 pl/sql 无法格式化插入脚本 .. 像上面的 pl/sql 期望列值在一行中.. 我已经生成了这些插入脚本并存储在 clob.now我想动态执行这个..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    相关资源
    最近更新 更多