有时我会得到一个脚本,它可以在 SQL Developer 或 Toad 中正常运行,但需要修改才能从 SQL*Plus 成功运行。这是一个包含多个语句的最坏情况示例,每个语句都带有空行、分号和正斜杠:
INSERT INTO t1 VALUES ('a
;
/
');
INSERT INTO t1 VALUES ('b
;
/
');
DELETE FROM t1 WHERE c1 = 'c
;
/
';
由于各种原因,这些语句需要从 SQL*Plus 运行。空白行很容易用一个简单的...
set sqlblanklines on
我知道sqlterminator
可以更改和/或关闭,但两者都需要修改代码,前者移动了问题而不解决它,也没有解决嵌入式斜杠问题。
最好的答案是通过以某种方式更改环境(如 sqlblanklines 所做的那样),允许这些语句在不修改的情况下运行。如果那是不可能的,那么也许有一种方法可以以编程方式修改脚本。我试图避免手动更改。
您可以通过使用 login.sql 来完成大部分操作。login.sql 在 - 令人惊讶 - 登录期间执行,并从您的 SQLPATH 或当前目录加载。对于您提供的示例,您确实选择了最坏的情况。
问题是 sqlterminator。无论您在其中放入什么,正斜杠都会作为免费的 sqlterminator 维护。接下来,sqlplus 首先扫描 sqlterminator 并在扫描到字符串终止符之前执行此操作。如果你问我,这是一个错误。正斜杠可以在字符串中使用,只要它不是单独的一行。一旦 sqlplus 找到指定为 sqlterminator 的字符,它就会忽略其他所有内容并停止读取。
可以处理正斜杠,只要它不是单独一行。
login.sql 包含:
leigh.sql 包含:
运行脚本:
无需摆弄开始/结束块。无法处理命令内部的 sqlterminator,无论它在哪里,在字符串中与否,都无法在字符串中的一行上单独处理带有正斜杠的行。
如果放置在 BEGIN...END 块中,带有空行和分号的插入语句将成功。可以使用脚本来完成此更改,但如果脚本包含无法在块内运行且不立即执行的 DDL 语句,则该脚本将失败。
此解决方案也无法解决嵌入式 / 问题。
我的解决方法:
似乎在 body 语句中忽略了命令终止符。