【问题标题】:SQL Server : call stored procedure with side effects for each row without using a cursorSQL Server:在不使用游标的情况下为每一行调用具有副作用的存储过程
【发布时间】:2013-05-21 01:58:48
【问题描述】:

在你说这与SQL Call Stored Procedure for each Row without using a cursor 相同之前,让我澄清一下我的问题:

存储过程确实有副作用。事实上,这都是关于这些副作用的,因为每次调用的结果都会影响进一步的处理。

可以这样想:表包含规则定义,而 proc 按字面意思 RBAR 执行这些规则,对另一个表进行更改。

在这些条件下,我看不到如何设置操作,CROSS APPLY 可能由于副作用而无法使用,但它也不是必需的,因为我并没有真正加入规则表并获得任何结果。

如果解决方案真的是 RBAR,我还应该尽量避免使用 CURSOR 吗?将 WHILE 与 READ TOP 1 WHERE Key > @Key 一起使用是更好的解决方案吗?为什么?

越搜越发现fast_forward read_only cursor是最简单最快的解决方案。

【问题讨论】:

  • A) 您使用的是哪个数据库? B)使用游标有什么问题?每个数据库选择查询都使用一个。
  • A) MS SQL Server 2012 B) 据说游标天生就不好。 SQL 查询确实使用游标,但它们: 1) 看起来简单而干净。 2) 不允许任何东西在它中间执行,并且 3) 保证游标最后是关闭的。如果没有别的,当有替代解决方案可用时使用光标是一种糟糕的编码风格。
  • @MOHCTP - 添加了 RBAR,但可以进行一些编辑。
  • 欢迎来到存储过程领域。也许你应该reconsider using stored procedures
  • @Bohemian 我可以解决所有这些问题,以证明我在这里使用存储过程的合理性,但我只给出主要的一点:我们的视图和警报操作仪表板基本上是一个暴露于查询。 SQL 是唯一的选择 其他原因,例如不可移植性,根本不适用,因为我们永远不会使用 MS SQL 以外的 SQL 版本:-)

标签: sql sql-server cursor rbar


【解决方案1】:

游标本来就是不好的

没有。游标很容易被误用,并且往往会被 SQL 新手所使用,因为他们来自过程背景,甚至没有听说过“基于集合”。光标有它们的位置,如果您评估了可用的方法并得出结论认为光标很合适,我会说使用一个。

使用WHILE 循环来隐藏你真正在做的是使用光标的事实也是我不建议这样做的。

最后一点-您提到了fast_forwardread_only-但另一个建议是local-这样,如果出现问题,至少在退出光标所在的范围时会清除光标运行 - 而不是在连接的生命周期内持续存在。

【讨论】:

    【解决方案2】:
            --- create one temp table using temprory talbe
            declare @test_Table  table (id int, num int, name varchar(50))
            --- fetch all data from your table to temp talbe
            insert into @test_Table (id,num,name)
            select id,number,name from TESTNUMBERS
    
            ----select * from TESTNUMBERS
    
            declare @count int
            declare @id int
            set @count=(select COUNT(1) from @test_Table)
            --- create while loop to work on particular row 
            while (@count <>0)
            begin
            set id=(select top 1 id from @test_Table)
            ---- do you task wiht that row and call your stored procedure on this row
            ---then delete that row form temp table variable 
            delete from @test_Table where id=@id
            --- decarease count to maintain loop 
            set @count=@count-1
            end
    

    您可以使用这种类型的循环来处理每一行,而无需使用游标。

    步骤:

    1. 在临时表中存储数据

    2. 获取所有行的计数

    3. 在循环中从临时表中获取前 1 行

    4. 在该行完成所有任务

    5. den 从临时表中删除该行

    6. 将计数递减 1

    6 如果有帮助,那就尽情享受吧.....

    【讨论】:

      猜你喜欢
      • 2010-12-12
      • 2014-09-24
      • 1970-01-01
      • 2016-01-27
      • 2019-08-01
      • 2017-07-17
      • 2021-07-30
      • 2015-07-03
      • 2010-09-20
      相关资源
      最近更新 更多