我有一些代码执行紧密循环以插入数千条+记录,最近当我引入<cfqueryparam>
时,CF崩溃。
像...一样的东西。
<cfquery>
<cfloop query="qBars">
INSERT INTO Foo
SET
xx = <cfqueryparam value="#qBars.aa#" sqltype="CF_SQL_VARCHAR">,
yy = <cfqueryparam value="#qBars.bb#" sqltype="CF_SQL_INTEGER">
</cfloop>
</cfquery>
这曾经在没有<cfqueryparam>
的情况下工作得很漂亮。但是,对于cfqueryparam,我想当qBars
的记录数量很大(10,000 +)时可能会出现问题。
现在......我该怎么办?重构要在DB级别处理的整个事情?
由于
答案 0 :(得分:8)
老实说,如果我需要将10k +记录加载到DB中,我就不会使用CFQUERY。您的数据库几乎肯定能够批量加载数据,因此我建议您进行调查。
我认为允许的最大绑定参数数量是数据库引擎设置的限制,而不是CF或底层JDBC。但是你没有提到你正在使用哪个数据库,因此很难在那里为你研究答案。
我做了一些窥探并为SQL Server找到了这个表:http://msdn.microsoft.com/en-us/library/ms143432.aspx。它没有具体提到内联查询可以有多少绑定参数,但是他们为proc或函数的params提到的2100的数字与我之前能够在列表中传递的参数的最大数量相同(喜欢WHERE IN子句)。我一直以为它是列表的最大大小,但实际上它可能实际上是一般的多少参数的截止值。这对你来说很容易测试...尝试你的循环1005迭代,看看它是否有效。然后尝试1006次迭代,我可能会期望它失败。
当然,如果你碰巧在SQL Server上......
另外,你说事情崩溃了,但是你没有说出错误是什么......当你提出这类问题时,包含这类信息总是有帮助的。
答案 1 :(得分:2)
安东尼有一个很好的建议......我会检查一下这会对你的问题产生什么影响。就个人而言,我倾向于重构。我在将数据密集型操作转移到数据库级别方面取得了巨大成功。
我目前负责解析和分析关键字的应用程序。解析器最初是用coldfusion编写的,效果很好。随着要处理的条目数量的增长(几乎呈指数级),流程本身变得非常缓慢。我用t-SQL重写了代码(我正在运行SS2K8),响应时间大大增加。 imho,重构是值得的,特别是在数据密集型操作上。
答案 2 :(得分:2)
我会将代码更改为
<cfloop query="qBars">
<cfquery>
INSERT INTO Foo
SET
xx = <cfqueryparam value="#qBars.aa#" sqltype="CF_SQL_VARCHAR">,
yy = <cfqueryparam value="#qBars.bb#" sqltype="CF_SQL_INTEGER">
</cfquery>
</cfloop>
看看会发生什么。如果可行的话,你可以在整个事件中包含一个&lt; cftransaction,它将在一个事务中发送所有插入而不是数千个。
答案 3 :(得分:2)
您也可以尝试:
INSERT INTO ''foo'' (''xx'',''yy'')
VALUES
<cfloop query="qBars">
(<cfqueryparam value="#qBars.aa#" sqltype="CF_SQL_VARCHAR">, <cfqueryparam value="#qBars.bb#" sqltype="CF_SQL_VARCHAR">)
<cfif NOT qBars.currentRecordcount eq qBars.recordcount>,</cfif>
</cfloop>
我认为这会奏效。我最近没有尝试过,但我很确定我过去曾经使用过它。我将此示例修改为另一个SO答案。