I have a Spring CRUD application, with an Oracle SQL database.
I have several integration tests and use the @Sql
annotation to run .sql files which put the database in a desired state before running the test. I have had no problem with any of my .sql scripts so far, although they have all be very simple INSERT and DROP statements.
I am now trying to set up a scenario in which the database holds thousands of records in a particular table. I am not bothered about the content, only the number of records.
In order to replicate this scenario, I have written the following SQL script:
DECLARE
id integer := 1;
BEGIN
WHILE id <= 3000
LOOP
INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE)
VALUES (id, 'John', 'Smith', 32);
id := id + 1;
END LOOP;
END;
I have ran this script using IntelliJ and it works as expected.
However, when I put the script into a @Sql annotation, I run into the following error:
org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [sql/setUp.sql]: DECLARE id integer := 1; nested exception is java.sql.SQLException: ORA-06550: line 1, column 23:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
I am at a loss as to the solution; I have encountered similar issues where the solution was just a missing semi-colon, but that doesn't seem to be the case here. What's even more mystifying is that I tried running the following script via the @Sql annotation:
BEGIN
INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE)
VALUES (1, 'John', 'Smith', 32);
END;
This produced the following error, which makes even less sense:
org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [sql/test.sql]: BEGIN INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE) VALUES (1, 'John', 'Smith', 32); nested exception is java.sql.SQLException: ORA-06550: line 1, column 87:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
;
Most interesting to note is that removing the BEGIN and END statements (leaving just the INSERT INTO statement) works.
So does Spring JDBC simply not support BEGIN/END blocks? Are there limitations to the pre test @Sql annotation that I'm not aware of? Or have I missed something painfully obvious?
;
to send individual statements (as JDBC itself only supports individual statement execution). To execute scripts like this usually requires switching or disabling statement terminators in some way to be able to send the whole thing. That means you will probably have to fine-tune the@SqlConfig
of the@Sql
(eg the value ofseparator
). – Mark Rotteveel@Sql
is to split on;
. So as far as Spring is concerned, after every;
it encounters, a new statement starts. – Mark RotteveelEND;
statement with just a single/
character in the first column. – Bob Jarvis - Reinstate Monica