【发布时间】:2015-09-14 20:13:23
【问题描述】:
我经常听说 while 循环和游标一样糟糕,我不相信这是真的。 从性能的角度来看,是从 C# 调用多个存储过程更好,还是允许一个存储过程解析 XML 数据并以循环方式调用过程?有没有比循环更好的方法在 SQL 中调用未知数量的存储过程?
让我解释一下
我必须设计和实施供应商消息传递系统。有一家第三方公司将 XML 消息发送给来自发件人的收件人。在任何给定时间,我的公司都可能是发件人或收件人。
我想出了一个使用 SQL while 循环来运行存储过程的设计,但我担心它在面对大量循环时可能表现不佳。
基本思路是: 发送者 --> 第三方(消息系统) --> 接收者
当我的公司是接收方时,我的问题可能会发生:
- 发件人向第三方公司发送消息
- 第三方公司发消息给我公司
- WCF 服务收到第三方公司的请求
- 调用存储过程,传递接收到的待解析消息的xml
- 此存储过程解析 xml 并在 XML 中查找消息
- 当循环遍历每条消息并调用存储过程来更新信息时,传递消息实例的 ID。
消息 XML 是这样的:
<envelope>
<to></to>
<from></from>
...
<messages>
<message>
<id></id>
...
<params>
<param>
<Name></Name>
<Value></Value>
<param>
...
</params>
</message>
...
</messages>
</envelope>
我可以在每次 XML 传输中接收或发送一条或多条消息。一次可能会收到多条消息。处理发送和接收 XML 的第三方公司的要求是我们始终以成功或失败进行响应。我们有一个 60 秒的超时窗口来响应。由于这些限制,我自然害怕无法在时限内完成我需要做的所有处理,导致超时。
因此,如果我在一次传输中找到消息 1、2 和 3,我将不得不运行存储过程 1、2 和 3。我有一个填充了消息 ID 和存储过程的临时表来运行。
所以While循环基本上是(没有检查这部分的有效性,只是随意的,因为我手边没有SP)
While select count(*) from #temptable > 0
begin
select top 1 @idMessage = idMessage, @spToRun = spToRun from #temptable
exec @spToRun @idMessage
delete from #temptable where idMessage = @idMessage
select @idMessage = null, @spToRun = null
end
我害怕将它投入生产,然后发现它运行得太慢了。有人给点建议吗?
【问题讨论】:
-
您的问题是#6。您有一个不基于集合的存储过程。所以你需要重新设计这个过程……或者像你一样做(糟糕的)循环。另一个想法是在 C# 中跨越多个线程/任务,并以这种方式一次发送一个。寻找“c#parallel foreach”.....但请记住,如果您的数据可能重叠,您可能会遇到竞争问题。
-
出于好奇,有没有办法以基于集合的方式调用 SQL 中的存储过程?
-
发送xml并粉碎它。
标签: c# xml wcf stored-procedures sql-server-2012