Search code examples
triggerssql-server-2000

Trigger to Update Table


I'm trying to create a trigger that will update my Orders Table with the order information that is found in the OrderDetail table. The detail table can have multiple rows for multiple items in an order. These are linked together by OrderID. What I have so far is:

CREATE TRIGGER AfterOrderDetailInsert ON OrderDetail 
AFTER INSERT AS
UPDATE Orders 
SET OrderTotal = (
    SELECT (
        SELECT Sum(orderdetail.quantity * OrderDetail.Price * 
            ( 1.0 -OrderDetail.ItemDiscount / 100.0 )
        )
        FROM orderdetail 
        WHERE OrderDetail.OrderId = Orders.OrderId
    ) * 
    ( 1 - Orders.OrderDiscount / 100.0 ) * 
    ( 1.0 - Orders.CustomerDiscount / 100.0 )     
    FROM OrderDetail 
    INNER JOIN Orders on OrderDetail.OrderID=Orders.OrderID 
    WHERE OrderDetail.OrderID IN (SELECT OrderID FROM Inserted)
) 

I'm getting an error now saying that the subquery returned more than 1 value. Shouldn't this be just returning a single total value? I've tried adding SUM so that its UPDATE Orders Set OrderTotal = SUM(SELECT (SELECT OrderTotal Stuff)), but that is giving me a syntax error before the first SELECT.

This is on SQL Server 2000.

EDIT: I've changed the query to AFTER insert since I want ordertotal to be updated after any insert

2nd Edit: I'm trying to include the inserted meta-table since that should contain the order ID of the latest inserted row and only one row will ever be inserted at a time. Now though I'm getting an error saying "Key column information is insufficient or incorrect. Too many rows were affected by update". And looking at the order total column, every row in my table gets updated with that order total. So I think I'm close, but I'm still missing something.


Solution

  • Okay, finally got it figured out. The trick ended up using the Inserted table's Order ID for everywhere OrderID is referenced in the query and for the Update Query so my final query looked like this:

    CREATE TRIGGER AfterOrderDetailInsert ON OrderDetail 
    AFTER INSERT AS
    UPDATE Orders 
    SET OrderTotal = (
    SELECT (
        SELECT Sum(orderdetail.quantity * OrderDetail.Price * 
            ( 1.0 -OrderDetail.ItemDiscount / 100.0 )
        )
        FROM orderdetail 
        WHERE OrderDetail.OrderId = Orders.OrderId AND OrderDetail.OrderID in
       (SELECT TOP 1 OrderID From Inserted)) * 
    ( 1 - Orders.OrderDiscount / 100.0 ) * 
    ( 1.0 - Orders.CustomerDiscount / 100.0 )     
    FROM OrderDetail 
    INNER JOIN Orders on OrderDetail.OrderID=Orders.OrderID 
    INNER JOIN INSERTED on Orders.OrderID=Inserted.OrderID
    ) WHERE Orders.OrderID IN (SELECT TOP 1 OrderID FROM Inserted)
    

    The main difference was I was never setting any condition for the update clause since I was mixing it up with the condition for the SELECT query.