如何在 CURSOR 循环内提交?
我试图看看是否可以在游标循环中执行更新,并且更新的数据在循环的第二次迭代期间得到反映。
DECLARE cur CURSOR
FOR SELECT [Product], [Customer], [Date], [Event] FROM MyTable
WHERE [Event] IS NULL
OPEN cur
FETCH NEXT INTO @Product, @Customer, @Date, @Event
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT * FROM MyTable WHERE [Event] = 'No Event' AND [Date] < @DATE
-- Now I update my Event value to 'No Event' for records whose date is less than @Date
UPDATE MyTable SET [Event] = 'No Event' WHERE [Product] = @Product AND [Customer] = @Customer AND [Date] < @DATE
FETCH NEXT INTO @Product, @Customer, @Date, @Event
END
CLOSE cur
DEALLOCATE cur
假设当sql执行时所有记录的Event列都是NULL 在上面的 sql 中,我在游标循环内执行选择来查询 MyTable,其中事件值为“无事件”,但即使我在下一行中进行更新,查询也不会返回任何值。 因此,我在想是否有可能更新表并且更新的数据会反映在游标循环的下一次迭代中。
感谢您的帮助, 贾维德
I am trying to see if its possible to perform Update within a cursor loop and this updated data gets reflected during the second iteration in the loop.
DECLARE cur CURSOR
FOR SELECT [Product], [Customer], [Date], [Event] FROM MyTable
WHERE [Event] IS NULL
OPEN cur
FETCH NEXT INTO @Product, @Customer, @Date, @Event
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT * FROM MyTable WHERE [Event] = 'No Event' AND [Date] < @DATE
-- Now I update my Event value to 'No Event' for records whose date is less than @Date
UPDATE MyTable SET [Event] = 'No Event' WHERE [Product] = @Product AND [Customer] = @Customer AND [Date] < @DATE
FETCH NEXT INTO @Product, @Customer, @Date, @Event
END
CLOSE cur
DEALLOCATE cur
Assume when the sql executes the Event column is NULL for all records
In the above sql, I am doing a select inside the cursor loop to query MyTable where Event value is 'No Event' but the query returns no value even though I am doing an update in the next line.
So, I am thinking if it is even possible to update a table and the updated data get reflected in the next iteration of the cursor loop.
Thanks for any help,
Javid
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,这里不需要光标。类似下面的内容将具有相同的语义(从所有
Event
均为NULL
的起始位置开始)并且效率更高。其次,关于标题中要在游标循环内提交的问题与其他地方相同。您只需要一个
COMMIT
语句。但是,如果您不在较大的事务中运行此操作,则UPDATE
语句无论如何都会自动提交。第三,你真正的问题似乎与提交无关。它与反映后续迭代中数据更新的游标有关。对于问题中的情况,您需要
DYNAMIC
光标并非所有查询都支持动态游标。问题中的代码可以,但如果没有
ORDER BY
,则无法确定行的处理顺序以及您是否会看到可见的结果。我添加了一个ORDER BY
和一个索引来支持这一点,以允许使用动态游标。如果您尝试以下操作,您将看到游标仅提取一行,因为日期按降序处理,并且当处理第一行时,表会更新,以便没有更多行符合下一次提取的条件。如果您注释掉游标循环内的
UPDATE
,则会获取所有三行。Firstly You shouldn't need a cursor here. Something like the following would have the same semantics (from a starting position where all
Event
areNULL
) and be more efficient.Secondly regarding the question in the title to commit inside a cursor loop is the same as anywhere else. You just need a
COMMIT
statement. However if you aren't running this inside a larger transaction theUPDATE
statement will be auto committed anyway.Thirdly Your real question doesn't seem to be about commit anyway. It is about the cursor reflecting updates to the data on subsequent iterations. For the case in the question you would need a
DYNAMIC
cursorNot all queries support dynamic cursors. The code in the question would but without an
ORDER BY
it is undeterministic what order the rows would be processed in and thus whether you would see visible results. I have added anORDER BY
and an index to support this to allow a dynamic cursor to be used.If you try the following you will see the cursor only fetches one row as the dates are processed in descending order and when the first row is processed the table is updated such that no more rows qualify for the next fetch. If you comment out the
UPDATE
inside the cursor loop all three rows are fetched.即使这有效,也不能保证正确的结果,因为您在查询中错过了
ORDER BY
子句。据此,可以更新所有记录、没有记录或记录的任何随机子集。
您能用简单的英语解释一下您的存储过程应该做什么吗?
Even if this worked, this would not guarantee the correct result since you miss an
ORDER BY
clause in your query.Depending on this, all records, no records or any random subset of records could be updated.
Could you please explain in plain English what your stored procedure should do?
使用下面的模板
Use Below template