我正在为表格
的大型条件运行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。换句话说,似乎没有办法使用这两个数据库的绑定值来拆分/转换上述条件。有没有办法绕过这个问题,没有内联所有绑定值?
答案 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和简单计划here和here的内容。通过SQL直接执行会导致缓存计划,因此您的里程可能会有所不同。
答案 1 :(得分:0)
我们在jOOQ中最终实现此功能的方法是,在遇到任何限制后,使用ControlFlowException
中止使用绑定值呈现SQL。限制是:
我们也在这里写了博客:
一旦达到此限制,ControlFlowException
就会在查询呈现网站上被捕获,只需重新呈现所有内联的绑定值 - 这总是有效的(直到您达到查询大小限制,如果有的话) ,当然)。
我们假设内联绑定值,以及在这些情况下发生的重复硬分析是正常的,因为执行计划可以真正重用这种高度动态的SQL的可能性很小。