我的問題是我想要做JDBC批量插入和檢索標識列的值。 MS SQL驅動程序不支持此功能。任何人都可以指導我如何解決這個問題?JDBC驅動程序不支持通過檢索標識列進行批量更新。爲什麼?
5
A
回答
5
正如在前面的問題here,.getGeneratedKeys
中提到的那樣,僅僅在.executeBatch
之後才適用於SQL Server。我只是確認這是仍在使用的
- SQL Server JDBC驅動程序(4.1預覽版),並
- JTDS(1.3.1)
所以,看來最新版本的情況下您只需單獨執行插入操作,而無需批次。也就是說,不是這樣的
String[] stringsToInsert = new String[] { "foo", "bar", "baz" };
try (PreparedStatement ps = conn.prepareStatement(
"INSERT INTO junk (textcol) VALUES (?)",
PreparedStatement.RETURN_GENERATED_KEYS)) {
for (String s : stringsToInsert) {
ps.setString(1, s);
ps.addBatch();
}
ps.executeBatch();
try (ResultSet rs = ps.getGeneratedKeys()) {
while (rs.next()) {
System.out.println(rs.getInt(1));
}
}
}
代碼,你需要使用這樣的代碼
String[] stringsToInsert = new String[] { "foo", "bar", "baz" };
try (PreparedStatement ps = conn.prepareStatement(
"INSERT INTO junk (textcol) VALUES (?)",
PreparedStatement.RETURN_GENERATED_KEYS)) {
for (String s : stringsToInsert) {
ps.setString(1, s);
if (ps.executeUpdate() > 0) {
try (ResultSet rs = ps.getGeneratedKeys()) {
rs.next();
System.out.println(rs.getInt(1));
}
}
}
}
請注意,您仍然可以使用.setAutoCommit(false)
並在交易執行插入,只是不在批次。
至於爲什麼該操作不被支持,一個JTDS功能要求here被申請了九(9)年前與其中一個答覆是
我得看看怎麼樣這個特性可以在jTDS中實現,然後再決定是否值得付出努力。
因爲無論JTDS也不是SQL Server的JDBC驅動程序已經實現了它(至少目前還沒有,它是on the radar爲Microsoft JDBC驅動程序),也許只是不適合該功能的需求就夠了。
附錄
作爲一種變通方法,我想這可能工作
String[] stringsToInsert = new String[] { "foo", "bar", "baz" };
try (Statement s = conn.createStatement()) {
s.executeUpdate(
"CREATE TABLE #StuffToInsert (" +
"id INT IDENTITY(1,1) PRIMARY KEY, " +
"textcol NVARCHAR(100)" +
")");
}
try (PreparedStatement ps = conn.prepareStatement(
"INSERT INTO #StuffToInsert (textcol) VALUES (?)")) {
for (String s : stringsToInsert) {
ps.setString(1, s);
ps.addBatch();
}
ps.executeBatch();
}
try (PreparedStatement ps = conn.prepareStatement(
"INSERT INTO junk (textcol) SELECT textcol FROM #StuffToInsert",
Statement.RETURN_GENERATED_KEYS)) {
ps.executeUpdate();
try (ResultSet rs = ps.getGeneratedKeys()) {
while (rs.next()) {
System.out.println(rs.getInt(1));
}
}
}
可惜.getGeneratedKeys
只返回該被插入的最後一行單生成的密鑰。
如果發送大量的個體(非批處理)插入通過網絡連接將是一個問題,那麼這個解決方法可能有所幫助:
String[] stringsToInsert = new String[] { "foo", "bar", "baz" };
try (Statement s = conn.createStatement()) {
s.executeUpdate(
"CREATE TABLE #StuffToInsert (" +
"id INT IDENTITY(1,1) PRIMARY KEY, " +
"textcol NVARCHAR(100)" +
")");
}
try (PreparedStatement ps = conn.prepareStatement(
"INSERT INTO #StuffToInsert (textcol) VALUES (?)")) {
for (String s : stringsToInsert) {
ps.setString(1, s);
ps.addBatch();
}
ps.executeBatch();
}
try (PreparedStatement ps = conn.prepareStatement(
"SET NOCOUNT ON; " +
"DECLARE @GeneratedKeys TABLE(id INT IDENTITY(1,1) PRIMARY KEY, newkey INT); " +
"DECLARE @text NVARCHAR(100); " +
"DECLARE crsr CURSOR FOR " +
" SELECT textcol FROM #StuffToInsert ORDER BY id; " +
"OPEN crsr; " +
"FETCH NEXT FROM crsr INTO @text; " +
"WHILE @@FETCH_STATUS = 0 " +
"BEGIN " +
" INSERT INTO junk (textcol) VALUES (@text); " +
" INSERT INTO @GeneratedKeys (newkey) SELECT @@IDENTITY; " +
" FETCH NEXT FROM crsr INTO @text; " +
"END " +
"CLOSE crsr; " +
"DEALLOCATE crsr; " +
"SELECT newkey FROM @GeneratedKeys ORDER BY id; ")) {
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getInt(1));
}
}
}
但這種做法不尊重自動提交在Java代碼中設置,所以回滾是不可能的。
0
這可能不是我常見的情況,我想.....這就是爲什麼jdbc驅動程序不支持這一點。
相關問題
- 1. Sqlite JDBC驅動程序不支持RETURN_GENERATED_KEYS
- 2. mariadb jdbc驅動程序blob更新不支持
- 3. 支持Android的Jdbc Odbc驅動程序
- 4. 爲什麼Oracle的驅動程序不支持READ_UNCOMMITTED?
- 5. 表通過最新ODBC驅動程序支持
- 6. 爲什麼JTDS比Microsoft JDBC驅動程序更快?
- 7. [亞馬遜] [JDBC](10220)驅動程序不支持
- 8. Do MySql Connector J JDBC驅動程序不支持連接池?
- 9. 是什麼在MySQL JDBC驅動程序
- 10. 什麼是jdbc驅動程序「org.gjt.mm.mysql.Driver」?
- 11. JDBC批量更新
- 12. 爲什麼ObservableCollection不支持批量更改?
- 13. 爲什麼JDBC驅動程序不需要H2
- 14. MongoDB的C#驅動程序檢索增量更新
- 15. Laravel 5.2 DBLIB驅動程序不支持
- 16. OpenGL不支持視頻驅動程序
- 17. 用C++驅動程序爲MongoDB進行全文檢索
- 18. SQL Server JDBC驅動程序是否支持異步操作?
- 19. 支持JDK 1.5和JDK 1.6的SQL Server JDBC驅動程序4.0
- 20. 是否有用於BigQuery的Google支持的JDBC驅動程序?
- 21. Postgresql JDBC驅動程序是否支持Pgpass身份驗證?
- 22. 什麼是Groovy Console/jdbc驅動程序標準的類路徑?
- 23. 批量更新通過JDBC批處理給人的SQLException通過TransactionImp
- 24. 泊塢窗機 - 通用驅動程序不支持啓動
- 25. 爲什麼不通過RaisePropertyChanged進行UI更新?
- 26. 無法通過批量修補程序執行Windows更新
- 27. 處理兩個JDBC驅動程序的通用JDBC驅動程序
- 28. 在Eclipse中爲Derby更新JDBC驅動程序10.9
- 29. 更改爲新的Oracle JDBC驅動程序?
- 30. org.hibernate.exception.ConstraintViolationException:無法執行JDBC批量更新
您是否嘗試過使用['Statement#getGeneratedKeys'](https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html#getGeneratedKeys--)? – 2014-11-22 15:32:27
明顯的解決方案:不要使用批量插入,而是在循環中用'getGeneratedKeys'完成正常的'executeUpdate'。 – 2014-11-23 09:06:51
@LuiggiMendoza SQL Server JDBC驅動程序不支持在批處理中執行插入操作(參考:[here](http://stackoverflow.com/q/13641832/2144390))。我剛剛測試了sqljdbc41.jar(版本4.1預覽版,最新版本,AFAIK),顯然仍然如此。 :( – 2014-11-23 12:15:45