【问题标题】:Oracle SQL script to build SQL script using dbms_output使用 dbms_output 构建 SQL 脚本的 Oracle SQL 脚本
【发布时间】:2013-08-24 04:31:26
【问题描述】:

这可能是个愚蠢的想法。我正在尝试编写一个 SQL*Plus .sql 脚本,我可以从 Windows 批处理文件中调用该脚本,该文件本身使用 dbms_output.put_line 生成一个新的 .sql 脚本。到目前为止,我的脚本是这样的:

set echo off;
set serverout on;

conn user@pass;

spool E:\new_script.sql

DECLARE

  CURSOR c_groups IS
    SELECT * FROM table;

  s varchar2(4000);

BEGIN

  dbms_output.put_line('BEGIN');

  FOR x IN c_groups LOOP
    s := 'INSERT INTO TABLE blah VALUES ('''||x.name||''','||x.id||');';
  END LOOP;

  dbms_output.put_line(s);

  dbms_output.put_line('COMMIT;');

  dbms_output.put_line('END;');
  dbms_output.put_line('/');

END;
/

spool off;
exit;

但是,当我这样做时,我的 new_script.sql 只是说 “PL/SQL 过程已成功完成。” 有什么想法可以让 dbms_out.put_line 实际显示他们的消息吗?

我实际上并没有这样做来构建插入语句 - 这些只是一个简单的示例,显示了我正在尝试做的事情的要点。

【问题讨论】:

    标签: oracle sqlplus dbms-output


    【解决方案1】:
    1. 您必须先连接,然后使用SET 命令。所以你的三个命令应该在

      这个订单:

      conn user@pass;
      set echo off;
      set serverout on;
      

      否则,serveroutput 参数将被设置为其默认值

      value,即OFF,这就是dbms_output.put_line()的原因

      没有按预期工作。

    2. 您应该在FOR 循环内执行dbms_output.put_line(s)

      FOR x IN c_groups LOOP
         s := 'INSERT INTO TABLE blah VALUES ('''||x.name||''','||x.id||');';
         dbms_output.put_line(s);
      END LOOP;
      

      此外,它对于 spool BEGIN .. END 块是多余的。 DML 语句

      (在这种情况下是一堆INSERT INTO 语句)以分号结尾将是

      执行得很好,没有被包含在 BEGIN END 块中。

    3. 当您使用 *.bat 文件运行脚本时,使用该文件可能会很有用

      以下命令:

      set feedback off;  -- To not spool messages like 
                         -- PL/SQL procedure successfully completed
      
      set termout off;   -- to suppress the output from a command line.
      
    4. 您的方法可能可以归结为一个简单的SELECT 声明:

      conn user@pass;
      
      set echo off;
      set serverout on;
      set feedback off;
      set termout off;
      set heading off;
      
      spool E:\new_script.sql
      
      SELECT 'INSERT INTO TABLE blah VALUES ('''||name||'''','||to_char(id)||');'
       FROM table;
      
      spool off;
      
      exit;
      

    【讨论】:

    • +1 但是添加BEGINEND; 可能是一个非常好的主意。在慢速网络上,处理一个 PL/SQL 块将比处理许多 SQL 语句快得多。虽然如果 PL/SQL 块很大,这种方法会产生 DIANA 错误。
    • 1) 我认为你在 SET 之前还是之后 CONN 并不重要。我的 SET ECHO ON 在这两个地方都工作。 2) 在现实生活中,dbms_output 调用在循环内;那是一个转录错误。此外,我的循环内部涉及设置变量的函数调用,这就是为什么我在那里有 BEGIN 和 END 的原因。 3)这些会很有用,谢谢。 4)这可以追溯到#2,因为我在循环中进行了更多处理。如果没有匿名的 BEGIN..END 块包裹整个事情,我可能已经完成了。虽然我最终使用了 UTL_FILE,但感谢您查看它。
    • @Tom serveroutput 参数确实很重要。 echo 参数无关紧要。
    【解决方案2】:

    SPOOL 将结果发送到文件;但它不能确保打印结果。启用打印到标准输出;使用SERVEROUTPUT 命令。

    set serveroutput on
    

    这通常是一种糟糕的处理方式;我知道您说过这不是您实际在做的事情,但 SQL 是一种基于集合的语言。尽可能批量处理。

    【讨论】:

      猜你喜欢
      • 2014-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多