使用 SQL*Plus 生成 SQL*Plus 脚本

发布于 2024-10-02 03:41:45 字数 820 浏览 9 评论 0原文

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

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

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 版本 11.2.0.1.0 Production,连接到 11gR2 实例。)

I want to generate a whole lot of SQL*Plus scripts by querying the data dictionary, but I'm hitting some problems and suspect I'm missing something obvious.

For example, when I execute the following in SQL*Plus I get 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

I tried using the line continuation character to avoid this error, but it puts the continuation character into the output:

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

Notice how the output has the - after DUAL;? I don't want that in the generated script.

One way I can get around this is to concatenate a lot of CHR() function calls to generate semicolons and linefeeds; but I hope I don't have to because these scripts being generated are very long, and having bits like ]'||CHR(59)||CHR(10)||q'[ scattered throughout the code makes it look very ugly and a pain to troubleshoot.

(I'm using SQL*Plus Release 11.2.0.1.0 Production, connecting to an 11gR2 instance.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

芯好空 2024-10-09 03:41:45

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

为了使其与实时打字一起工作,如果您确实想这样做(如果它们很长,则似乎不太可能!),您可以使用 设置 SQLTERMINATOR 关闭。请注意,您必须告诉 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 生成您要假脱机的输出,只要最终的输出文件大小不会超过缓冲区限制。

The problem is that SQL*Plus is interpreting your first ; as the terminator for the command. You may have noticed that if you write your commands to a text file and execute that (or edit it in a text editor from with SQL*Plus) it works.

To make it work with live typing, if you really want to do that (seems unlikely if they're going to be very long!), you can turn off the automatic detection of the terminator with SET SQLTERMINATOR off. Note that you'll have to tell SQL*Plus that you're done and that it should execute with the / instruction as the second ; is ignored as well.

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.

If you're building these from the data dictionary, another option is to use PL/SQL to do the queries and manipulations and dbms_output to produce the output you're gong to spool, as long as the final file size won't exceed the buffer limits.

遗心遗梦遗幸福 2024-10-09 03:41:45

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

When I want to create a script from within the DB I tend to prefer writing a file using the UTL_FILE package instead of spooling the output of SQL*Plus. It isn't exactly what you want, but I find the control to be far less troublesome than trying to write sql scripts that format properly.

漫漫岁月 2024-10-09 03:41:45

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

You can use getddl in dbms_metada package or mine package:
http://github.com/xtender/XT_SVN

蛮可爱 2024-10-09 03:41:45

您需要查看 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 (;).

You need to see 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 (;).
忘年祭陌 2024-10-09 03:41:45

为了供我自己将来参考,在使用sql plus时不要乱搞SET SQLTERMINATOR off,而是使用下面的命令,这样你就不需要担心任何特殊的sql终止符字符串文字体内的字符。

BEGIN
INSERT INTO SOME_TABLE (q'[ 

Now;
You;
Can '
Do "'"';' ;;;
any character? *

]');
END;
/

For future reference for myself, instead of messing around with SET SQLTERMINATOR off when using sql plus use the following bellow so you don't need to worry about the any special sql terminator character inside the string literal body.

BEGIN
INSERT INTO SOME_TABLE (q'[ 

Now;
You;
Can '
Do "'"';' ;;;
any character? *

]');
END;
/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文