I have a bunch of sql scripts (some sql and some plsql) to be executed using ant . Before I start the execution, I need to make sure that the files are executable. So I run the following target to create sql and plsql executable from ant.
<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>
And the PLSQL in the file a file is something like this -
BEGIN
FOR c IN
--query
LOOP
dbms_utility.blah ;
END LOOP;
COMMIT;
END;
/
that when ant target makeExecutableSQLs runs outputs -
BEGIN
FOR c IN
--query
LOOP
dbms_utility.blah
/
END LOOP
/
COMMIT
/
END
;
/
but this when running later fails due to this error -
Error starting at line : 1 in command - BEGIN FOR c IN --query LOOP dbms_utility.blah Error report - ORA-06550: line 9, column 135: PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
:= . ( % ; 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
Cant put a finger on where the error is?
The PL/SQL errors are thrown because you have replaced semicolon PL/SQL statement separators with block terminators.
When the compiler sees the /
it terminates and executes the command in the buffer, so it sees and tries to compile and run
BEGIN
FOR c IN
--query
LOOP
dbms_utility.blah
/
as a standalone complete PL/SQL block. As the error you get from that
ORA-06550: line 9, column 135: PLS-00103: Encountered the symbol "end-of-file" ...
indicates that apparently-complete block ends before it is supposed to. There is no semicolon statement terminator after blah
, but also no end loop
or end
for the block - in that code it is trying to execute. It hasn't seen the rest of the script, effectively.
It then carries on and tries to interpret the next chunk
END LOOP
/
which is also invalid; the client doesn't even try to execute that because it doesn't know what to do with it.
Then the next chunk
COMMIT
/
is successfully run as a plain SQL (transaction control) statement, not in a PL/SQL context.
And so on.
In short, you cannot replace semicolons with slashes within a PL/SQL block as they do very different things. In plain SQL they are interchangeable (or rather, to most clients they are; at least by default - even in SQL*Plus you can change the SQL terminator from a semicolon to something else).
The client still handles the slash after a PL/SQL block, and when it sees that it sends the block to the DB to be executed. But while it knows it is inside a block it knows any semicolons it sees are part of the PL/SQL language and it shouldn't try to interpret them.
This is referred to in the SQL*Plus documentation for running PL/SQL blocks , and other clients tend to behave in similar ways.
Execute the current subprogram with a
RUN
or slash (/
) command. A semicolon (;
) is treated as part of the PL/SQL subprogram and will not execute the command.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.