更新语句的 JDBC 占位符限制的解决方法失败
Posted
技术标签:
【中文标题】更新语句的 JDBC 占位符限制的解决方法失败【英文标题】:Workaround for JDBC Limitation on Placeholders Fails for Update Statements 【发布时间】:2013-05-16 00:36:18 【问题描述】:我正在实现一种模式来解决 JDBC 限制。对于准备好的语句,JDBC 将占位符的数量限制为 2100。为了解决这个问题,我使用了一个包含 2100 多个值的 xml 字符串,并使用函数 tf_splitxml 在 SQL Server 端解析它。我正在为 ~4 个使用准备好的语句的 Java 方法执行此操作。
这个 tf_splitxml 只是构造一个包含所有值的单列“令牌”。所以一个xml字符串:
'<node><value>1</value><value>2</value></node>'
将转换为包含两行的列,其值为 1 和 2。
这种模式似乎适用于 select 语句,但不适用于 update 语句。这是一般模式:
declare @xml xml; set @xml = ?; --Replaced with xml string in PreparedStatement
update tableX
...
where ids in (select token from tf_splitxml(@xml));
它告诉我在将 nvarchar 值转换为数据类型 int 时转换失败。 [对于上述 xml 字符串]。奇怪的是,如果我提取prepared statement设置的查询,我可以在SQL Server中完美运行!
我的想法:
-
在 4 种方法中,3 种使用这种 xml 模式;这 3 个都是 select 语句并使用 executeQuery()。第 4 个失败的方法是更新语句并使用 executeUpdate()。也许问题与prepared statement预编译sql的方式有关?
我尝试过的事情:
我创建了一个表,可以保存从 tf_splitxml 生成的令牌。对于失败的方法,在 JDBC 抛出错误之前永远不会调用 tf_splitxml。
在 Java 端,我使用的是 ps.setString(index, convertToXML(idsArray))。这适用于前 3 种方法,即使我的 @xml 不是字符串(它被声明为 xml 变量)。我尝试将其切换到 SQLXML 对象,但无济于事。我仍然可以正常使用相同的 3/4 方法。
我可以直接在我的 SQL Server 编辑器中运行所有准备好的查询。
提前致以最诚挚的谢意! :)
【问题讨论】:
jdbc 对占位符的数量没有指定限制;它是您的特定驱动程序或数据库。 对不起,我的意思是 SQLServer。你是对的马克。 :) 【参考方案1】:该代码看起来很疯狂,请查看我的ChunkWorkTemplate。这是一个简单的例子:
public void delete(final List<Integer> employeeIds)
new ChunkWorkTemplate<Integer>(50, employeeIds)
protected void executeOnChunk(List<Integer> chunk)
Session session = getSession();
Query query = session.createSQLQuery("delete from Employee where employeeId in (:employeeIds)");
query.setParameterList("employeeIds", chunk);
query.executeUpdate();
.execute();
请注意,模板的第一个参数是块大小,您可以将其设置为您喜欢的任何值。基本上,它会将输入集合分块并分块执行主体。因此,在上面的示例中,如果您有 207 个员工 ID,块大小为 50,您将有 5 个块 (50+50+50+50+7)。我写这篇文章是为了解决您面临的确切问题。希望这会有所帮助。
【讨论】:
嗨乔纳森!感谢您的输入。是的,这适用于我可以分块的情况。但是,如果我说:select * from tableA inner join tableB 嗨乔纳森!感谢您的输入。这仅适用于我可以分块的情况。如果我在多个连接表上执行 select 语句,您可能会遇到多个问题: 1. 批处理,这也会遇到重复处理。 2.返回错误数据。 (对于 NOT IN 子句,分块并不容易。)以上是关于更新语句的 JDBC 占位符限制的解决方法失败的主要内容,如果未能解决你的问题,请参考以下文章
请问下在java jdbc中:sql语句中含有or 时,该如何为这个占位符(?)赋值····求解 如下图: