yuv*_*raj 5 java sql-server jdbc
我的问题是我想做JDBC批量插入和检索标识列值.MS SQL驱动程序不支持此功能.有人可以指导我,如何解决这个问题?
如前面提到的问题在这里,.getGeneratedKeys根本不工作后.executeBatch的SQL Server.我刚刚确认使用最新版本的情况仍然如此
因此,您似乎只需要单独执行插入操作,而无需批处理.也就是说,而不是像这样的代码
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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
你需要使用这样的代码
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));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,您仍然可以.setAutoCommit(false)在事务中使用和执行插入操作,而不是批量操作.
至于为什么不支持该操作,这里提出的jTDS功能请求是在九(9)年前提交的,其中一个响应是
在确定是否值得付出努力之前,我将不得不看一看如何在jTDS中实现这样的功能.
由于jTDS和SQL Server JDBC驱动程序都没有实现它(至少现在还没有;它是微软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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
但不幸的是,.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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是这种方法不尊重Java代码中的AutoCommit设置,因此无法进行回滚.
| 归档时间: |
|
| 查看次数: |
1393 次 |
| 最近记录: |