从存储过程调用多个存储过程-sqlwhile循环

本文关键字:存储过程 -sqlwhile 循环 调用 | 更新日期: 2023-09-27 18:12:53

我经常听说while循环和游标一样糟糕,我不相信这是真的从性能的角度来看,从C#调用多个存储过程更好,还是允许存储过程解析XML数据并以循环方式调用过程更好?有没有比循环更好的方法来调用SQL中未知数量的存储过程

让我解释一下

我必须设计和实现一个供应商消息传递系统。有一个第三方公司向接收方发送源自发送方的XML消息。我的公司可能是任何特定时间的发送者或接收者。

我提出了一种使用SQLwhile循环来运行存储过程的设计,但我担心它在面对大量循环时可能不会很好地执行。

基本思想是:发送方-->第三方(消息系统(-->接收方

当我的公司是接收者时,我的问题可能会发生:

  1. 发件人向第三方公司发送消息
  2. 第三方公司向我的公司发送消息
  3. WCF服务接收来自第三方公司的请求
  4. 调用一个存储过程,传递要解析的接收消息的xml
  5. 此存储过程解析xml并在xml中查找消息
  6. While循环遍历每条消息并调用一个存储过程来更新信息,传递消息实例的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

我害怕把它投入生产,然后发现它运行得太慢了。有人有什么建议吗?

从存储过程调用多个存储过程-sqlwhile循环

我的建议是继续使用C#来解析xml,并根据需要从dotnet端调用sprocs(只要您保持sql简洁(。显然,我并不完全熟悉您的情况,但根据我的经验,调试sql存储的proc很困难,尤其是当它们的逻辑/处理量很大时,就像您正在做的那样,即使您使用的是游标/循环。在c#这样的环境中,控制更细粒度,在那里你可以放置断点,在处理过程中观察内存中变量(或者在你的情况下是xml节点(的值,并捕捉更广泛的错误,这在从第三方接收文件时非常有帮助。此外,虽然您可能认为sql在性能上与dot-net一样好,但它不是中间件,它通常在后端为您提供最佳服务。通常在许多组织中,sql server在后端有足够的工作要做,而且,在未来,如果你发现你对sql server的要求太高,它会开始对你表现得很奇怪,你可能会发现你的sql server负担过重。最后,就性能而言,我认为好处超过了额外的行程时间,如果您保持sql的简单性并将其编译为存储的proc,并且如果您将其放在生产服务器上,那么无论如何都应该可以减轻额外的行程时间。至少,如果出于性能原因不得不这样做,我会在偏向C#/dotnet的情况下取得平衡,并依靠sql server尽可能少地进行处理。

对于高达1MB的xml,我不会在存储过程中对其进行切碎而眨眼。(您没有说明xml中有多少行(。

您将获得比逐行发送更好的性能。

如果您的内存超过1MB,请考虑使用goldie locks方法。不要一个接一个地发送,也不要"全部"发送,而是要有一个外部c进程,将xml分解成更小的部分。例如:一个有100500行的文件,一次发送10000行,发送11次。

您可以使用goldie locks方法玩数字游戏。

我会在C#中验证你的xml,然后我会把它作为我所说的"perfectXml"发送到sql server,然后把它分解成一个#temp表,然后从那里插入。同样,这是关键,xml应该是"完美的",因为您没有在tsql中对其运行检查以及if和this或that语句。

一排排痛苦的排是给鸟儿的。