2014-10-02 61 views
0

我试图做一个简单的更新语句在我的数据库,如以下解决一些数据:将触发器连接到该表时不能更新列值?

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 
+1

触发文本与此处相关。更新的行数不相关,因为更新的每一行都会触发触发器。问题是我认为在触发器本身,因为在触发器内的子查询没有返回一个唯一的记录。我们需要查看触发器更新部分中的文本。 – xQbert 2014-10-02 18:01:06

+0

我编辑了我的帖子,添加了触发代码的哑版。你是对的,似乎问题是我从“插入”和“插入”的数据是多个记录导致它失败。由于管理原因,我无法更改触发器,所以我试图提出一个Update语句来绕过此限制。我知道我可以做一个光标并循环遍历每个记录并单独更新,但必须有一个更好/更简单的方法,对吧? – user3653673 2014-10-02 18:09:39

+0

您的触发器代码在这里似乎有一个主要缺陷。你的代码不会处理多行操作。在触发器中设置基于代码是至关重要的。当你有这样的标量值时,你不能准确地处理它。 – 2014-10-02 18:17:44

回答

0

在你触发你可能有情况是这样的:

where ProductID = (Select ProductId From SalesTable) 

看看你是否可以把它改成

where ProductID IN (Select ProductId From SalesTable) 

是的触发器文本是与此有关。

+0

感谢您的回应。如果您再次查看我的帖子,我添加了触发代码。我相信问题在于我从“插入”中获取值。如果一次只更新一条记录,那就可以正常工作。如果我一次更新多个,它不能从“插入”中获取值。 – user3653673 2014-10-02 18:18:28

0
-- 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是一个整数,不能将行数据作为其赋值。

我想你可以通过在循环中运行更新语句来解决这个问题,一次只做一行。但真正的解决方案是更新触发器。我相信我们可以提供一些关于如何这样做的建议 - 虽然你说过你无法更新触发器。

+0

感谢您的回复。我也在考虑做一个循环,但我希望有一个更简单的方法。另一位用户在我选择使用的评论中发布了一个解决方案。他建议禁用触发器,运行语句,然后再次启用触发器。 – user3653673 2014-10-02 19:10:30

1

感谢xQbert在我的问题下留言,解决了我的问题,而无需重写我的触发器。他的解决方案是禁用触发器,进行更新,然后在更新后重新启用触发器。由于当我运行更新时我的系统将被关闭,这将工作正常。但是,如果您在实时系统中遇到同样的问题,那么在执行此操作时也应该在表格上加锁。

ALTER TABLE SalesTable DISABLE TRIGGER SalesTrigger 

UPDATE SalesTable 
    SET ProductId = NULL 
WHERE ProductId = 0 

ALTER TABLE SalesTable ENABLE TRIGGER SalesTrigger 
+0

+1非常出色的工作,以正确的语法考虑你的评论并作出回答。我很高兴你收到了所需的指导,并且自己开发解决方案。 (并且让人们这样思考,不,这不是讽刺) – xQbert 2014-10-03 13:09:28