【问题标题】:Generating SQL*Plus script using SQL*Plus使用 SQL*Plus 生成 SQL*Plus 脚本
【发布时间】:2014-06-11 14:11:12
【问题描述】:

我想通过查询数据字典来生成大量 SQL*Plus 脚本,但我遇到了一些问题并且怀疑我遗漏了一些明显的东西。

例如,当我在 SQL*Plus 中执行以下命令时,我得到 ORA-01756: quoted string not properly terminated:

SQL> SPOOL myscript.sql
SQL> SELECT q'[SPOOL log
  2  SELECT COUNT(*) FROM DUAL;
ERROR:
ORA-01756: quoted string not properly terminated

我尝试使用续行符来避免此错误,但它会将续行符放入输出中:

SQL> SELECT q'[SPOOL log
  2  SELECT COUNT(*) FROM DUAL; -
  3  PROMPT Done.
  4  ]' FROM DUAL;
SPOOL log
SELECT COUNT(*) FROM DUAL; -
PROMPT Done.

注意DUAL; 后面的- 是如何输出的?我不希望在生成的脚本中出现这种情况。

我可以解决这个问题的一种方法是连接大量 CHR() 函数调用以生成分号和换行符;但我希望我不必这样做,因为生成的这些脚本非常长,并且在代码中散布着像 ]'||CHR(59)||CHR(10)||q'[ 这样的位,这使得它看起来非常难看并且很难解决。

(我正在使用 SQL*Plus Release 11.2.0.1.0 Production,连接到 11gR2 实例。)

【问题讨论】:

    标签: oracle sqlplus


    【解决方案1】:

    问题在于 SQL*Plus 将您的第一个 ; 解释为命令的终止符。您可能已经注意到,如果您将命令写入文本文件并执行(或使用 SQL*Plus 在文本编辑器中编辑它),它会起作用。

    要使其与实时输入一起使用,如果您真的想这样做(如果它们会很长,这似乎不太可能!),您可以使用SET SQLTERMINATOR off 关闭终止符的自动检测。请注意,您必须告诉 SQL*Plus 您已完成,它应该使用 / 指令执行,因为第二个 ; 也会被忽略。

    SQL> SPOOL myscript.sql
    SQL> SET SQLTERMINATOR off
    SQL> SELECT q'[SPOOL log
      2  SELECT COUNT(*) FROM DUAL;
      3  PROMPT Done.
      4  ]' FROM DUAL
      5  /
    SPOOL log
    SELECT COUNT(*) FROM DUAL;
    PROMPT Done.
    

    如果您是从数据字典构建这些,另一种选择是使用 PL/SQL 进行查询和操作,并使用 dbms_output 生成您要假脱机的输出,只要最终文件大小不会超过缓冲区限制。

    【讨论】:

    • dbms_output!我每天都在使用它……但也感谢SQLTERMINATOR 选项。
    • (顺便说一句,当我从脚本运行它时,这种行为仍然会发生。)
    • 啊,是的,它当然可以,SQLPlus 会像您键入它一样解释它。如果您在 SQL 中edit 就可以了Plus,我猜这会绕过 SQL*Net 试图解释它。
    【解决方案2】:

    当我想从数据库中创建脚本时,我倾向于使用UTL_FILE 包编写文件,而不是假脱机 SQL*Plus 的输出。 完全不是你想要的,但我发现控件比尝试编写格式正确的 sql 脚本要麻烦得多。

    【讨论】:

    • 我想过,但是我需要访问服务器上的目录,然后我需要通过 FTP 获取文件或通过终端会话运行 sql*plus。我宁愿使用 CHR() 连接:) - 我现在正在做的事情是转存到一个更方便的本地文件。
    • 完全明白。在特定环境中获得这种访问权限并不总是那么容易。
    【解决方案3】:

    您可以在 dbms_metada 包或我的包中使用 getddl: http://github.com/xtender/XT_SVN

    【讨论】:

    • 没有。 getddl只适合生成Oracle知道的DDL。我想生成自己的脚本 - 包含 SET 命令、提示、查询、DML 等。
    【解决方案4】:

    你需要看到http://download.oracle.com/docs/cd/A97630_01/server.920/a90842/ch13.htm

    SET CMDS[EP] {;|c|ON|OFF}
    
    Sets the non-alphanumeric character used to separate multiple SQL*Plus commands entered on one line to c. ON or OFF controls whether you can enter multiple commands on a line. ON automatically sets the command separator character to a semicolon (;).
    

    【讨论】:

      【解决方案5】:

      为了我自己的未来参考,使用 sql plus 时不要乱用SET SQLTERMINATOR off,请使用以下内容,这样您就不必担心字符串中的任何特殊 sql 终止符正文。

      BEGIN
      INSERT INTO SOME_TABLE (q'[ 
      
      Now;
      You;
      Can '
      Do "'"';' ;;;
      any character? *
      
      ]');
      END;
      /
      

      【讨论】:

      • 不确定为什么要将脚本插入表中...?
      猜你喜欢
      • 2019-06-06
      • 2012-11-13
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 2013-10-17
      • 2010-12-17
      • 2020-07-14
      • 2012-05-11
      相关资源
      最近更新 更多