JDBC で batchInsert をやるには、
- rewriteBatchedStatements = true
- useServerPrepStmts = false
テーブル
CREATE TABLE testtbl(selector_type INT);
Java
Class.forName("com.mysql.jdbc.Driver").newInstance(); Properties prop = new Properties(); prop.setProperty("user", "testuser"); prop.setProperty("password", "password"); prop.setProperty("characterEncoding", "utf8"); prop.setProperty("rewriteBatchedStatements", "true"); prop.setProperty("useServerPrepStmts", "false"); try (Connection con= DriverManager.getConnection("jdbc:mysql://localhost/testdb", prop)) { PreparedStatement stmt = con.prepareStatement("INSERT INTO testtbl (selector_type) VALUES (?)"); for (int i = 0; i < 10; ++i) { stmt.setInt(1, i); stmt.addBatch(); } stmt.executeBatch(); }
結果
2019-02-27T02:28:18.112397Z 19 Query INSERT INTO testtbl (selector_type) VALUES (0); 2019-02-27T02:28:18.112734Z 19 Query INSERT INTO testtbl (selector_type) VALUES (1); 2019-02-27T02:28:18.112853Z 19 Query INSERT INTO testtbl (selector_type) VALUES (2); 2019-02-27T02:28:18.113839Z 19 Query INSERT INTO testtbl (selector_type) VALUES (3); 2019-02-27T02:28:18.113953Z 19 Query INSERT INTO testtbl (selector_type) VALUES (4); 2019-02-27T02:28:18.114038Z 19 Query INSERT INTO testtbl (selector_type) VALUES (5); 2019-02-27T02:28:18.114121Z 19 Query INSERT INTO testtbl (selector_type) VALUES (6); 2019-02-27T02:28:18.114202Z 19 Query INSERT INTO testtbl (selector_type) VALUES (7); 2019-02-27T02:28:18.114291Z 19 Query INSERT INTO testtbl (selector_type) VALUES (8); 2019-02-27T02:28:18.114370Z 19 Query INSERT INTO testtbl (selector_type) VALUES (9)
VALUES のあとにスペースが必要との情報もあったが、既についてる・・・
JDBC ドライバーのソースを追ってみたところ、PreparedStatement クラスに
if (StringUtils.indexOfIgnoreCase(statementStartPos, sql, "SELECT", "\"'`", "\"'`", StringUtils.SEARCH_MODE__MRK_COM_WS) != -1) { return false; }的なコードが・・・
SELECT INSERT を除外しているようだが、もしやということで、カラム名をバッククウォートで囲ったところ
Java
snip ... PreparedStatement stmt = con.prepareStatement("INSERT INTO testtbl (`selector_type`) VALUES (?)"); snip ...
結果
2019-02-27T02:28:39.536756Z 20 Query INSERT INTO testtbl (`selector_type`) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)連結されて、1 文で実行されることに!
SQL 文の中に SELECT という文字があるとダメな模様。
さらに調べてみると、既に報告が上がっていた。
https://bugs.mysql.com/bug.php?id=81468
2016 年 5 月・・・
0 件のコメント:
コメントを投稿