tags:

views:

144

answers:

5

I am using Java, Spring (NamedParameterJdbcTemplate) and MySQL. My statement looks like this:

INSERT INTO Table1 (Name) VALUES (?);
INSERT INTO Table2 (Path, Table1Id) VALUES (?, LAST_INSERT_ID())

But it is throwing the following error:

PreparedStatementCallback; bad SQL grammar [INSERT INTO Table1 (Name) VALUES (?);
INSERT INTO Table2 (Path, Table1Id) VALUES (?, LAST_INSERT_ID())] `

Nested exception is:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO Table2 (Path, Table1Id' at line 1

The syntax works fine in MySQL but something is up when combining via the Spring template.

Thanks!

A: 

You need to execute each statement separately. First, insert into table1, then insert into table2

a1ex07
No I don't! I want to batch them, I've got 100,000 inserts to do, that's why I need to do it in one statement
MalcomTucker
+2  A: 

Use the addBatch method to run multiple statements


Statement stmt = con.createStatement();
   stmt.addBatch(
    "update registration set balance=balance-5.00
        where theuser="+theuser);
   stmt.addBatch(
    "insert into auctionitems(
                   description, startprice) 
        values("+description+","+startprice+")");

   int[] results = stmt.executeBatch();

source

marcos
+1  A: 

The MySQL JDBC driver doesn't support multiple statements separated by ';', even if the MySQL client itself does. You can't depend on that if you must do this with Java.

If you have 100K records, are you sure that Java is the right tool for the job? I'd wonder if MySQL import tools or ETL would be better if this is a batch job.

Also, what about the Spring batch module? Does it have anything specially made for this problem?

duffymo
ok, so that's the answer i was after (or not, but it's answered my question!). the problem i have is getting the inserted id from the first table for the subsequent insert. at the moment i am having to execute one at a time - is there a technique for batching two related inserts like this?
MalcomTucker
Try looking at java.sql.Statement.getGeneratedKeys. It'll be INSERT, getGeneratedKeys, INSERT in one unit of work. Make sure you do it in a single transaction. You know how to do transactions, right?
duffymo
Yeah no problem - can i return them in bulk though?
MalcomTucker
I don't know. The method say "keys" (plural), but I've only used it for a single row at a time. I've never used it in a batch situation.
duffymo
A: 

did you miss the semicolon ; in the second statement. I think this is a syntax error than anything else.

trying running there two commands on the mysql console and se if the syntax is correct.

I always run the coomand on console to make sure the sytax.

A: 

For anyone who wants to execute multiple statements from jdbcTemplate with MySQL without using batch update:

Add "?allowMultiQueries=true" at the end of the url (see example below).

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/tt?allowMultiQueries=true" />
    <property name="username" value="root" />
    <property name="password" value="" />
</bean>

Tested with jdbcTemplate.execute method, Spring 3.0.2 and MySQL driver v5.1.9

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.9</version>
    </dependency>
tomasz.koscinski