2015-04-22 6 views
0

Я в настоящее время работает над мини-проектом, который включает в себя несколько таблиц: Invoice и InventoryInsert Триггер Вычитание значения

Оба эти таблицы имеют Product_Id и Quantity, и мне нужно написать триггер, так что, когда создается новый Invoice, он уменьшает количество продукта в таблице Inventory. Любая помощь приветствуется.

CREATE TRIGGER tr_UpdateQuantity 
ON Invoice 
AFTER INSERT 
AS 
BEGIN 
    UPDATE Inventory 
    SET Inventory.Quantity = Inventory.Quantity - Invoice.Quantity 
    FROM Invoice 
    WHERE Inventory.Product_Id = Invoice.Product_Id 
END 
+1

Какой DBMS? (Большинство dbms-продуктов не соответствуют требованиям ANSI SQL, когда речь заходит о триггерах.) – jarlh

+0

Если у вас также есть таблица, в которой записаны полученные товары, было бы гораздо лучше покончить с столбцом количества в таблице инвентаря целиком. Вы всегда сможете * вычислить количество на основе транзакционных данных (вы могли бы реализовать некоторые индексированные представления, чтобы эта информация была легко доступна, если это необходимо). Всегда предпочитайте не хранить * рассчитанные * данные. –

ответ

0

Я предполагаю, что вы используете SQL Server на основе синтаксиса, который вы попытались.

Вы можете сделать это:

CREATE TRIGGER tr_UpdateQuantity 
ON Invoice 
AFTER INSERT 
AS 
BEGIN 
DECLARE 
@ProductId numeric, 
@Quantity numeric 

    SELECT @ProductId = INSERTED.Product_Id, 
      @Quantity = INSERTED.quantity 
    FROM INSERTED 

    UPDATE Inventory 
    SET Quantity = Quantity - @Quantity 
    WHERE Product_Id = @ProductId 

END; 

В основном вы захватить PRODUCT_ID и количество из вставленной таблицы и использовать их в своем UPDATE заявление. См. Документацию MSDN в таблице INSERTED: https://msdn.microsoft.com/en-us/library/ms191300.aspx

Как упоминалось в комментарии по вашему вопросу, если у вас есть какой-либо контроль над вашей схемой, вы должны подумать о том, чтобы не хранить производные данные. Вы можете легко получить данные через представление или другую структуру без возможности синхронизации данных.

Обновление до исходного/принятого ответа: как указывали другие, приведенное выше не учитывает вставку более одной записи, и в этом случае вам необходимо присоединиться к таблице INSERTED.

+0

Это «выглядит правильно». Я попробую это, когда вернусь домой сегодня вечером. Что касается @Damien_The_Unbeliever, это в настоящее время является изрядным школьным заданием, чтобы получить 2 разных типа триггеров для работы над нашей созданной БД, так что в настоящее время в живых условиях спасибо за совет. Btw его очень оценили :-) – prola

+0

Работал как очарование вы очень сэр. – prola

+0

Этот триггер сломан. Он предполагает, что 'вставленный' содержит одну строку, которая не является безопасным предположением. –

3

Было бы лучше, если вы сделаете это для массовой вставки:

CREATE TRIGGER tr_UpdateQuantity ON Invoice 
AFTER INSERT 
AS 
BEGIN 

    UPDATE inv 
    SET Quantity = Quantity - i.Quantity 
    FROM Inventory inv 
    JOIN (SELECT Product_ID, SUM(Quantity) AS Quantity FROM INSERTED GROUP BY Product_ID) i ON inv.Product_ID = i.Product_ID 

END; 
Смежные вопросы