带有 cfqueryparam 的 cfquery 可以获得多长时间是否有限制?
我有一些代码执行紧密循环来插入数千条记录,最近当我引入
时,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,我想当 qBars 的记录计数很大(10,000+)时可能会出现问题。
现在……我该怎么办?重构整个事情以在数据库级别处理?
谢谢
I have some code that does a tight loop to insert thousands+ records and recently when I introduce <cfqueryparam>
, CF crashes.
Something like...
<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>
This used to work beautifully without <cfqueryparam>
. With cfqueryparam however, I guess it might be problematic when the recordcount of qBars
is large (10,000+).
Now... What shall I do? Refactor the whole thing to be handled in DB level?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
老实说,如果我需要将 10k 以上的记录加载到数据库中,我不会使用 CFQUERY。您的数据库几乎肯定具有批量加载数据的能力,因此我建议对此进行研究。
我认为允许的绑定参数的最大数量将是由数据库引擎设置的限制,而不是由 CF 或底层 JDBC 设置。但是您没有提及您正在使用哪个数据库,因此很难在那里为您研究答案。
我做了一些窥探,发现了 SQL Server 的这张表: http://msdn. microsoft.com/en-us/library/ms143432.aspx。它没有具体提到内联查询可以有多少个绑定参数,但是他们提到的过程或函数参数的 2100 个数字与我之前能够在列表中传递的参数的最大数量相同(就像 WHERE IN 子句一样)。我一直认为这是列表的最大大小,但也许它实际上是一般参数数量的截止值。这对您来说测试起来很容易...尝试 1005 次迭代的循环,看看它是否有效。然后尝试 1006 次迭代,我可能会认为它会失败。
也就是说,当然,如果您碰巧在 SQL Server 上...
另外,您说事情崩溃了,但您没有说错误是什么...当您“时,包含此类信息总是有帮助的”正在问这种问题。
To be honest, if I was needing to load 10k+ records into the DB, I would not use CFQUERY. Your DB will almost certainly have the capability to bulk load data, so I recommend investigating that.
I think the maximum number of bind parameters allowed would be a restriction set by the DB engine rather than by CF or the underlying JDBC. But you don't mention which DB you're using, so it's hard to research an answer for you there.
I did some snooping around and found this table for SQL Server: http://msdn.microsoft.com/en-us/library/ms143432.aspx. It does not specifically mention how many bind params an inline query can have, but the figure of 2100 they mention for params for a proc or function is the same as the maximum number of parameters I've been able to pass in a list before (like for a WHERE IN clause). I always thought it was the maximum size for a list, but perhaps it's actually the cut off for how many params in general. This would be easy for you to test... try your loop with 1005 iterations and see if it works. Then try it with 1006 iterations, and me might expect it to fail.
That is, of course, if you happen to be on SQL Server...
Also, you say the thing crashes, but you don't say what the error is... it's always helpful to include this sort of information when you're asking this sort of question.
安东尼有一个很好的建议......我会检查一下这对你的问题有什么影响。就我个人而言,我倾向于重构。我在将数据密集型操作转移到数据库级别方面取得了巨大成功。
我目前负责一个解析和分析关键字的应用程序。该解析器最初是用 Coldfusion 编写的,效果很好。随着要处理的条目量增长(几乎呈指数级增长),处理本身变得非常缓慢。我用 t-SQL 重写了代码(我正在运行 SS2K8),响应时间显着增加。恕我直言,重构是值得花时间的,尤其是在数据密集型操作上。
Antony has a good suggestion... I would check to see what impact this has on your problem. Personally, I'd lean towards refactoring. I've had great success in moving data intensive operations to the database level.
I'm currently responsible for an application that parses and analyzes keywords. The parser was originally written in coldfusion, which worked great. As the volume of entries to process grew (almost exponentially), the process itself became very slow. I rewrote the code in t-SQL (I'm running SS2K8) and the response time increased substantially. imho, refactoring is worth the time, especially on data intensive operations.
我会将代码更改为
看看会发生什么。如果可行,您可以将整个事务包裹一个
I would change the code to
And see what happens. If that works, you can wrap a <cftransaction around the whole thing which will send all the inserts in one transaction rather than thousands.
你也可以尝试:
我认为这会起作用。我最近没有尝试过,但我很确定我过去用过它。我修改了这个例子以获得另一个答案。
You could also try:
I think this will work. I have not tried it recently, but I am pretty sure I have used it in the past. I modified this example for another SO answer.