将触发器连接到该表时不能更新列值?
我试图做一个简单的更新语句在我的数据库,如以下解决一些数据:将触发器连接到该表时不能更新列值?
UPDATE SalesTable
SET ProductId = NULL
WHERE ProductId = 0
我只是想为0的任何值切换回空。该列可以为空,并且已经有一些空记录。问题似乎是我有一个附加到SalesTable的触发器,当对该表进行更新时触发。它似乎并不喜欢我的更新语句一次更新多行。我如何解决这个问题?
以下是错误消息是否有帮助:
子查询返回多个值。当子查询遵循=, !=, <, <= , >, >=
或子查询用作表达式时,这是不允许的。
这是触发器的一个虚拟版本。不确定是否重要,但ProductId字段未在触发器中使用。
DECLARE @salesId int
DECLARE @salesDate DateTime2
DECLARE @customerName varchar(50)
SELECT @salesId = s.SalesId,
@salesDate = s.SalesDate,
@customerName = c.CustomerName
FROM Inserted s
INNER JOIN Customer c
ON s.CustomerId = c.CustomerId
UPDATE SalesSummary
SET SalesId = @salesId,
SalesDate = @salesDate,
CustomerName = @customerName
WHERE SalesId = @salesId
在你触发你可能有情况是这样的:
where ProductID = (Select ProductId From SalesTable)
看看你是否可以把它改成
where ProductID IN (Select ProductId From SalesTable)
是的触发器文本是与此有关。
感谢您的回应。如果您再次查看我的帖子,我添加了触发代码。我相信问题在于我从“插入”中获取值。如果一次只更新一条记录,那就可以正常工作。如果我一次更新多个,它不能从“插入”中获取值。 – user3653673 2014-10-02 18:18:28
-- Here's your problem
SELECT @salesId = s.SalesId,
@salesDate = s.SalesDate,
@customerName = c.CustomerName
FROM Inserted s INNER JOIN Customer c on s.CustomerId = c.CustomerId
UPDATE SalesSummary SET
SalesId = @salesId,
SalesDate = @salesDate,
CustomerName = @customerName
WHERE SalesId = @salesId
使用@salesId为例 - 当更新一个记录(比如salesId 1)@salesId被正确地分配给从插入
然而,当多个行被同时更新,说1,2, 3,4,5,@salesId是一个整数,不能将行数据作为其赋值。
我想你可以通过在循环中运行更新语句来解决这个问题,一次只做一行。但真正的解决方案是更新触发器。我相信我们可以提供一些关于如何这样做的建议 - 虽然你说过你无法更新触发器。
感谢您的回复。我也在考虑做一个循环,但我希望有一个更简单的方法。另一位用户在我选择使用的评论中发布了一个解决方案。他建议禁用触发器,运行语句,然后再次启用触发器。 – user3653673 2014-10-02 19:10:30
感谢xQbert在我的问题下留言,解决了我的问题,而无需重写我的触发器。他的解决方案是禁用触发器,进行更新,然后在更新后重新启用触发器。由于当我运行更新时我的系统将被关闭,这将工作正常。但是,如果您在实时系统中遇到同样的问题,那么在执行此操作时也应该在表格上加锁。
ALTER TABLE SalesTable DISABLE TRIGGER SalesTrigger
UPDATE SalesTable
SET ProductId = NULL
WHERE ProductId = 0
ALTER TABLE SalesTable ENABLE TRIGGER SalesTrigger
+1非常出色的工作,以正确的语法考虑你的评论并作出回答。我很高兴你收到了所需的指导,并且自己开发解决方案。 (并且让人们这样思考,不,这不是讽刺) – xQbert 2014-10-03 13:09:28
触发文本与此处相关。更新的行数不相关,因为更新的每一行都会触发触发器。问题是我认为在触发器本身,因为在触发器内的子查询没有返回一个唯一的记录。我们需要查看触发器更新部分中的文本。 – xQbert 2014-10-02 18:01:06
我编辑了我的帖子,添加了触发代码的哑版。你是对的,似乎问题是我从“插入”和“插入”的数据是多个记录导致它失败。由于管理原因,我无法更改触发器,所以我试图提出一个Update语句来绕过此限制。我知道我可以做一个光标并循环遍历每个记录并单独更新,但必须有一个更好/更简单的方法,对吧? – user3653673 2014-10-02 18:09:39
您的触发器代码在这里似乎有一个主要缺陷。你的代码不会处理多行操作。在触发器中设置基于代码是至关重要的。当你有这样的标量值时,你不能准确地处理它。 – 2014-10-02 18:17:44