如何规避Sybase ASE和SQL Server的最大绑定值数

时间:2012-06-29 17:50:38

标签: sql-server jdbc sybase-ase jooq bind-variables

我正在为表格

的大型条件运行jOOQ集成测试
WHERE x IN (:1, :2, :3, :4, ..., :3001, :3002)

上面的例子描述了在IN条件下有许多绑定变量。 Oracle在IN条件的括号之间有1000个值(绑定值或内联值)的众所周知的限制。解决方案很简单,只需写:

WHERE x IN (:1, :2, :3, :4, ..., :1000) OR x IN (:1001, ...)
另一方面,Sybase ASE 15.5和SQL Server 2008 R8似乎对绑定值的数量有一个总体限制:Sybase ASE为2000,SQL Server为2100。换句话说,似乎没有办法使用这两个数据库的绑定值来拆分/转换上述条件。有没有办法绕过这个问题,没有内联所有绑定值?

2 个答案:

答案 0 :(得分:1)

如果您创建了表格类型,然后说出IN (SELECT column FROM @variableThatIsMyTableType),那么您根本不受限制。

我不会反复使用MSDN - 其中包含table types and table valued parameters here

然后生成的SQL看起来像:

DECLARE @variableThatIsMyTableType mySchema.myTableType
INSERT @variableThatIsMyTableType VALUES (1)
INSERT @variableThatIsMyTableType VALUES (2)
EXEC proc @variableThatIsMyTableType

然而,当从C#和SqlClient提交时,它会创建所谓的“琐碎计划” - 您可以阅读有关TVP和简单计划herehere的内容。通过SQL直接执行会导致缓存计划,因此您的里程可能会有所不同。

答案 1 :(得分:0)

我们在jOOQ中最终实现此功能的方法是,在遇到任何限制后,使用ControlFlowException中止使用绑定值呈现SQL。限制是:

  • SQLite:999
  • Ingres 10.1.0:1024
  • Sybase ASE 15.5:2000
  • SQL Server 2008:2100

我们也在这里写了博客:

一旦达到此限制,ControlFlowException就会在查询呈现网站上被捕获,只需重新呈现所有内联的绑定值 - 这总是有效的(直到您达到查询大小限制,如果有的话) ,当然)。

我们假设内联绑定值,以及在这些情况下发生的重复硬分析是正常的,因为执行计划可以真正重用这种高度动态的SQL的可能性很小。