java 标识列如何处理_JDBC驱动程序不支持通过检索标识列进行批量更新。为什么? - java...

我的问题是我想做JDBC批处理插入和检索标识列值。 MS SQL驱动程序不支持此功能。有人可以指导我,如何解决这个问题?

参考方案

如前面的问题here所述,对于SQL Server,.getGeneratedKeys在.executeBatch之后根本不起作用。我只是确认使用最新版本的仍然如此

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驱动程序都尚未实现(至少尚未实现;对于Microsoft JDBC驱动程序,它是on the radar),因此可能对该功能的需求不足。

附录

作为解决方法,我认为这可能有效

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代码中的AutoCommit设置,因此无法回滚。

Java-搜索字符串数组中的字符串 - java

在Java中,我们是否有任何方法可以发现特定字符串是字符串数组的一部分。我可以避免出现一个循环。例如String [] array = {"AA","BB","CC" }; string x = "BB" 我想要一个if (some condition to tell wheth…Java Scanner读取文件的奇怪行为 - java

因此,在使用Scanner类从文件读取内容时,我遇到了一个有趣的问题。基本上,我试图从目录中读取解析应用程序生成的多个输出文件,以计算一些准确性指标。基本上,我的代码只是遍历目录中的每个文件,并使用扫描仪将其打开以处理内容。无论出于何种原因,扫描程序都不会读取其中的一些文件(所有UTF-8编码)。即使文件不是空的,scanner.hasNextLine()在…Java Globbing模式以匹配目录和文件 - java

我正在使用递归函数遍历根目录下的文件。我只想提取*.txt文件,但不想排除目录。现在,我的代码如下所示:val stream = Files.newDirectoryStream(head, "*.txt") 但是这样做将不会匹配任何目录,并且返回的iterator()是False。我使用的是Mac,所以我不想包含的噪音文件是.DS_ST…直接读取Zip文件中的文件-Java - java

我的情况是我有一个包含一些文件(txt,png,...)的zip文件,我想直接按它们的名称读取它,我已经测试了以下代码,但没有结果(NullPointerExcepion):InputStream in = Main.class.getResourceAsStream("/resouces/zipfile/test.txt"); Buff…Java RegEx中的单词边界\ b - java

我在使用\b作为Java Regex中的单词定界符时遇到困难。对于text = "/* sql statement */ INSERT INTO someTable"; Pattern.compile("(?i)\binsert\b");找不到匹配项Pattern insPtrn = Pattern.compile(&…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值