我想要实现的目标
我们的数据库中有一个名为 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。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。 声明已经终止。
有人会有什么建议我如何更好地/不同地接近这个?
非常感谢
答案 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
列是唯一的,这将有效。