Sql server 在sql server中插入/更新触发器以检查值

Sql server 在sql server中插入/更新触发器以检查值,sql-server,Sql Server,我不熟悉SQL Server和触发器。我有一个现有的触发器需要定制。有两个表Products,其中包含库存产品的总量。数量和订单行,其中包含有关订单的所有信息。示例行中包含OrderID、ProductID和Amount 当我下订单时,保留产品数量。 我需要触发器来检查新订购的数量是否超过数量。如果是,抛出RAISERROR;如果不是,则让事务继续 我在识别总订单号以核对库存数量方面遇到了问题 触发器用于OrdersLines表 我想做一些事情,大致如下: IF EXISTS ((SELECT

我不熟悉SQL Server和触发器。我有一个现有的触发器需要定制。有两个表Products,其中包含库存产品的总量。数量和订单行,其中包含有关订单的所有信息。示例行中包含OrderID、ProductID和Amount 当我下订单时,保留产品数量。 我需要触发器来检查新订购的数量是否超过数量。如果是,抛出RAISERROR;如果不是,则让事务继续

我在识别总订单号以核对库存数量方面遇到了问题

触发器用于OrdersLines表 我想做一些事情,大致如下:

IF EXISTS ((SELECT *
            FROM Products AS p
            JOIN inserted AS i
            ON p.ProductID = i.ProductID
            JOIN OrdersLines AS o
            ON p.ProductID = o.ProductID
            WHERE (SUM(o.Amount) + i.Amount) <= p.Quantity)
BEGIN 
    GOTO ContinueTransaction
END ELSE BEGIN
    GOTO RollbackTransaction
    END

但我认为这是不对的。此外,在其他我需要RAISERROR通知,订单没有添加,但我不知道如何添加。有一些论点需要摆在那里,现在让我感到困惑

问题通过以下方法解决。
create trigger CheckOrderAmount 
On orderLines 
for insert, update
As 
Begin
Set NoCount On;

   if exists (Select * from inserted I
                 join products p
                    on p.ProductID = i.ProductID
              group by i.ProductID 
              having SUM(i.Amount) > p.Quantity)
    begin
      rollback transaction
      raiserror("There are not enough items in inventory", 16, 1)
    end
end
对于插入触发器:

IF EXISTS (SELECT * 
            FROM atbv_Sales_Products p 
            JOIN inserted i
            ON p.ProductID = i.ProductID
            JOIN atbv_Sales_OrdersLines ol
            ON p.ProductID = i.ProductID
            GROUP BY i.ProductID, i.Amount, p.Quantity
            HAVING (SUM(ol.Amount) + i.Amount) > p.Quantity)
BEGIN
    DECLARE @ProductName NVARCHAR(60)
            SET @ProductName = (SELECT p.ProductName 
                                    FROM atbv_Sales_Products p
                                    JOIN inserted i 
                                    ON i.ProductID = p.ProductID)
            RAISERROR ('----There is not enough items (%s) left----', 18, 1, @ProductName) ROLLBACK TRANSACTION 
            RETURN
END 
IF EXISTS (SELECT * 
            FROM atbv_Sales_Products p 
            JOIN atbv_Sales_OrdersLines ol
            ON ol.ProductID = p.ProductID
            GROUP BY p.ProductID, ol.Amount, p.Quantity
            HAVING SUM(ol.Amount) > p.Quantity)
BEGIN
    DECLARE @ProductName NVARCHAR(60)
            SET @ProductName = (SELECT p.ProductName 
                                    FROM atbv_Sales_Products p
                                    JOIN atbv_Sales_OrdersLines ol
                                    ON ol.ProductID = p.ProductID
                                    GROUP BY p.ProductID, ol.Amount, p.Quantity, p.ProductName
                                    HAVING SUM(ol.Amount) > p.Quantity)
            RAISERROR ('----There is not enough items (%s) left----', 18, 1, @ProductName) ROLLBACK TRANSACTION 
            RETURN
END                     
对于更新触发器:

IF EXISTS (SELECT * 
            FROM atbv_Sales_Products p 
            JOIN inserted i
            ON p.ProductID = i.ProductID
            JOIN atbv_Sales_OrdersLines ol
            ON p.ProductID = i.ProductID
            GROUP BY i.ProductID, i.Amount, p.Quantity
            HAVING (SUM(ol.Amount) + i.Amount) > p.Quantity)
BEGIN
    DECLARE @ProductName NVARCHAR(60)
            SET @ProductName = (SELECT p.ProductName 
                                    FROM atbv_Sales_Products p
                                    JOIN inserted i 
                                    ON i.ProductID = p.ProductID)
            RAISERROR ('----There is not enough items (%s) left----', 18, 1, @ProductName) ROLLBACK TRANSACTION 
            RETURN
END 
IF EXISTS (SELECT * 
            FROM atbv_Sales_Products p 
            JOIN atbv_Sales_OrdersLines ol
            ON ol.ProductID = p.ProductID
            GROUP BY p.ProductID, ol.Amount, p.Quantity
            HAVING SUM(ol.Amount) > p.Quantity)
BEGIN
    DECLARE @ProductName NVARCHAR(60)
            SET @ProductName = (SELECT p.ProductName 
                                    FROM atbv_Sales_Products p
                                    JOIN atbv_Sales_OrdersLines ol
                                    ON ol.ProductID = p.ProductID
                                    GROUP BY p.ProductID, ol.Amount, p.Quantity, p.ProductName
                                    HAVING SUM(ol.Amount) > p.Quantity)
            RAISERROR ('----There is not enough items (%s) left----', 18, 1, @ProductName) ROLLBACK TRANSACTION 
            RETURN
END                     

插入的表不是只包含插入的新行吗?或者换句话说,它没有insert之前存在的行?编辑:如果库存中有足够的商品,我们的示例回滚事务也不会发生吗?还有,如果不是太多,为什么是16,1?是的,但它有所有的列,包括那些你没有改变的列。插入订单后,您不是在更新产品表中的数量吗?若您是,那个么您只需要确保这些新订单不超过当前剩余数量,对吗?并且只有当插入的新订单中的金额总和超过当前数量时,它才会回滚事务。回滚位于begin end块内,该块的条件是exists为true。但我忘记了这是基于Sum的,因此exists需要是一个聚合group By查询,谓词需要位于Having子句中,而不是where子句中。我编辑了答案以反映这一点。然后返回到更新products.quantity。当然,您不能在插入订单的同一SQL语句中对其进行更新,但必须在订单插入后立即使用另一个SQL语句(update语句)对其进行更新,作为执行订单插入的同一事务的一部分。否则,这一过程将不起作用。在插入订单的任何时候,“数量”列中的值都必须准确表示在过帐前下订单时库存中的项目数。