我有一堆使用ant执行的sql脚本(一些sql和一些plsql)。 在开始执行之前,我需要确保文件是可执行的。因此,我运行以下目标以从ant创建sql和plsql可执行文件。
<copy todir="${migration.scripts.dir}\temp\">
<fileset dir="${migration.scripts.dir}" includes="*.sql"/>
<filterchain>
<replaceregex byline="false" pattern=";" replace="${line.separator}/" flags="mg"/>
<replaceregex byline="false" pattern="/[\s]*/" replace=";${line.separator}/" flags="mg"/>
</filterchain>
</copy>
文件中的PLSQL文件就是这样-
BEGIN
FOR c IN
--query
LOOP
dbms_utility.blah ;
END LOOP;
COMMIT;
END;
/
当蚂蚁目标makeExecutableSQLs运行时输出-
BEGIN
FOR c IN
--query
LOOP
dbms_utility.blah
/
END LOOP
/
COMMIT
/
END
;
/
,但是稍后由于此错误而失败-
从第1行开始的错误- 开始 对于输入 -查询 环 dbms_utility.blah 错误报告 - ORA-06550:第9行,第135列: PLS-00103:预期以下情况之一时遇到符号“文件结尾”:
:= . ( % ; 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. *Action: Error starting at line : 11 in command - END LOOP Error report - Unknown Command Commit complete. Error starting at line : 15 in command - END Error report - Unknown Command Error starting at line : 16 in command - Error report - Unknown Command
不能把手指放在哪里出错了?
答案 0 :(得分:2)
由于已用块终止符替换了分号PL / SQL语句分隔符,因此引发了PL / SQL错误。
当编译器看到/
时,它终止并在缓冲区中执行命令,因此它看到并尝试编译并运行
BEGIN
FOR c IN
--query
LOOP
dbms_utility.blah
/
作为独立的完整PL / SQL块。作为您从中得到的错误
ORA-06550:第9行,第135列:PLS-00103:遇到了符号“文件结束” ...
表示看似完整的块在应该完成之前就结束了。 blah
之后没有分号语句终止符,但该块也没有end loop
或end
-在它试图执行的代码中。它没有有效地看到脚本的其余部分。
然后继续进行并尝试解释下一个块
END LOOP
/
这也是无效的;客户端甚至不尝试执行该操作,因为它不知道该如何处理。
然后再下一个块
COMMIT
/
成功作为普通SQL(事务控制)语句运行,而不是在PL / SQL上下文中运行。
以此类推。
简而言之,您不能在PL / SQL块中用斜杠替换分号,因为它们做的事情非常不同。在普通SQL中,它们是可互换的(或者,对于大多数客户端而言,它们是可互换的;至少在默认情况下,即使在SQL * Plus中,您也可以将SQL终止符从分号更改为其他值)。
客户端仍然在PL / SQL块之后处理斜线,并且当它看到将其发送到要执行的DB时。但是,尽管它知道它在 内部,但它知道所看到的任何分号都是PL / SQL语言的一部分,因此不应尝试解释它们。
这被称为in the SQL*Plus documentation for running PL/SQL blocks,其他客户端的行为往往类似。
使用
RUN
或斜杠(/
)命令执行当前子程序。分号(;
)被视为PL / SQL子程序的一部分,并且不会执行该命令。