0

We have two tables: one that contains products and another one that has the order information.

CREATE TABLE [dbo].[ORDERS] 
  ( 
     [ROW]           [BIGINT] IDENTITY(1, 1) NOT NULL, 
     [ID]            [UNIQUEIDENTIFIER] NOT NULL, 
     [RETAILER_ID]   [UNIQUEIDENTIFIER] NOT NULL, 
     [INDIVIDUAL_ID] [UNIQUEIDENTIFIER] NOT NULL, 
     [PRODUCT_ID]    [UNIQUEIDENTIFIER] NOT NULL, 
     [QUANTITY]      [BIGINT] NOT NULL, 
     [DATE]          [DATETIME] NOT NULL, 
     [MEMO]          [NVARCHAR](MAX) NULL 
  ) 
ON [PRIMARY] 
TEXTIMAGE_ON [PRIMARY] 

CREATE TABLE [dbo].[PRODUCTS] 
  ( 
     [ROW]         [BIGINT] IDENTITY(1, 1) NOT NULL, 
     [ID]          [UNIQUEIDENTIFIER] NOT NULL, 
     [RETAILER_ID] [UNIQUEIDENTIFIER] NOT NULL, 
     [NAME]        [NVARCHAR](255) NOT NULL 
  ) 
ON [PRIMARY] 

We need to fix this Trigger so that when a name of a product changes, the memo field in the orders table needs to have a remark about that change in the orders table. So here is the trigger that we designed but we are getting errors "The multi-part identifier "o.Memo" could not be bound."

Here is the trigger that generates errors? Where did we go wrong?

CREATE TRIGGER DBO.PRODUCTS_NAME_CHG 
ON DBO.PRODUCTS 
AFTER UPDATE 
AS 
  BEGIN 
      -- SET NOCOUNT ON added to prevent extra result sets from 
      -- interfering with SELECT statements. 
      DECLARE @old NVARCHAR(255), 
              @new NVARCHAR(255), 
              @ID  UNIQUEIDENTIFIER 

      SELECT @ID = ID, 
             @old = NAME 
      FROM   DELETED 

      SELECT @NEW = NAME 
      FROM   INSERTED 

      SET NOCOUNT ON; 

      IF UPDATE (NAME) 
        BEGIN 
            UPDATE DBO.ORDERS 
            SET    o.MEMO = o.MEMO + ' ' + @OLD + ' HAS CHANGED NAME TO ' + @NEW 
                            + '. ' 
            FROM   ORDERS o 
                   INNER JOIN PRODUCTS P 
                           ON P.ID = O.PRODUCT_ID 
            WHERE  P.ID = @ID 
        END 
  END 

GO 
2
  • 2
    Never assume that there will always be one record in inserted and deleted tables. Sql Server fires triggers once per statement, not per row, so this trigger will fail to notice change of name if you decide to update bunch of records at once. The join of inserted, deleted and base table will produce all the info you need to update base table. Commented Sep 2, 2013 at 19:49
  • if update(name) does not ensure that name has changed; it merely expresses that name took part in update query. This will prove problematic if you work with an ORM that updates all the columns. Use where inserted.name <> deleted.name in update query in addition to if update(name) test. If name is nullable you will have to devise more complicated criteria. Commented Sep 2, 2013 at 19:50

1 Answer 1

3

Well, the syntax for an update with an inner join should be

UPDATE o -- use alias here, not table name.
  SET o.Memo = --blabla
  FROM Orders o
  INNER JOIN --blabla
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.