SQL迭代失败

时间:2015-06-26 13:32:06

标签: sql sql-server loops iteration

我想要实现的目标

我们的数据库中有一个名为 pstats 的表,它专注于一次为一个用户保留一个人的记录。该表保存每个人的记录并添加用户的唯一ID并将其放在 lockedby 字段中以保留它,否则在解锁时它为0。这样只允许用户在软件中打开时编辑此记录,当软件窗口关闭时,软件通过将关联的人员记录 lockedby 字段设置为0来释放记录,从而允许其他用户编辑它如果他们请。

我似乎遇到的问题是,有一个报告或程序会将记录锁定到一个用户,从而阻止其他人访问这些人员记录。这是我正在努力解决的问题。

同时,当您使用以下命令查询 pstats 表时症状非常明显:

select * From pstats where lockedby != 0

由于其中一个用户ID属于30,40,50个人记录 lockedby 字段,例如:

pcode    |   lockedby
----------------------
100212        100025
100304        100025
100810        100025
100835        100025
100980        100025
117092        100025
117472        100025
117907        100025

我执行的准则

为了尝试对此提供一些解脱,我可以使用以下方法手动设置个人记录:

Update sysDatabase.dbo.pstats set lockedby = 0 where pcode = 100212

你可以想象,当有30多条记录需要修改并且需要时间来解决这个问题的根源时,这是相当费时的。所以我试着变得更聪明一点,并以 IN 语句的形式尝试一种循环/列表形式,如下所示:

select * From pstats where lockedby != 0
Update sysDatabase.dbo.pstats set lockedby = 0 where pcode IN (100212,
100304,
100810,
100835,
100980,
117092,
117472,
117907)

我收到的错误讯息

不幸的是,这似乎并没有像我希望的那样有效,并且我在运行时遇到以下错误:

  

(受影响的8行)   消息512,级别16,状态1,过程tr_pstats_Update,第4行   子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。   声明已经终止。

有人会有什么建议我如何更好地/不同地接近这个?

非常感谢

1 个答案:

答案 0 :(得分:1)

错误是不言自明的:

  

消息512,级别16,状态1,过程tr_pstats_Update

您在表tr_pstats_Update上有一个触发器,该触发器一次只能用于一行更新,可能看起来像这样:

CREATE TRIGGER tr_pstats_Update ON sysDatabase.dbo.pstats
AFTER UPDATE
AS
BEGIN
    DECLARE @id INT
    SET @id = (SELECT ID FROM DELETED)
END

错误是由这一行引起的;

SET @id = (SELECT ID FROM DELETED)

DELETED将包含多行,因为您要更新表中的多行。

解决此问题的一种方法是重写触发器以加入DELETED表。 另一种方法是在此语句上使用游标并分别更新每个pcode

select * from (values(100212),
                     (100304),
                     (100810),
                     (100835),
                     (100980),
                     (117092),
                     (117472),
                     (117907)) t(pcode)

如果您的表格中pcode列是唯一的,这将有效。