Insert Trigger Help

  • Sql novice here, need help with an insert trigger please.

    I have a 'Customer' database with customerid, name, email...

    Attempting to create an insert trigger to create a CustomerLog table. When a customer places an order, i'll pass in the customer id, which should do the following:

    - CustomerLogID will autocount

    - CustomerID (pass in)

    - email, should pull from 'Customer' database that corresponds to customerid

    - get date.

    What values do I enter in the "Insert Into" line of the create trigger query?

    -- INSERT TRIGGER

    Create Table CustomerLog (CustomerLogID int Identity, CustomerID int, Email varchar(100), LogDate varchar(20))

    CREATE TRIGGER tgrCustomerInsert ON Customer FOR INSERT

    AS

    DECLARE @CustomerID int

    Select @CustomerID = CustomerID From inserted

    INSERT INTO CustomerLog (CustomerLogId, CustomerID, Email, LogDate)

    Values(CustomerLogId, @CustomerID, Email, GetDate())

    GO

    Insert Into CustomerLog (Id) Values(?)

    Select * From CustomerLog

  • lfc8ynwa (3/3/2012)


    DECLARE @CustomerID int

    Select @CustomerID = CustomerID From inserted

    The first problem is that you are assuming there will only ever be one row inserted at a time. What's going to happen if inserted has 2 rows?

    Typically, if you want to create a logging trigger, it will look something like the following.

    CREATE TRIGGER....

    AS

    INSERT INTO <logging table name> (<columns to insert>)

    SELECT <columns> from inserted

    Try using that kind of pattern. You shouldn't be assigning variables from inserted because the trigger will 'break' if there are multiple rows in the inserted table.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Ok. thanks.

    Any help on the values to enter in the Insert Into line?

  • See my previous post, specifically

    Typically, if you want to create a logging trigger, it will look something like the following.

    CREATE TRIGGER....

    AS

    INSERT INTO <logging table name> (<columns to insert>)

    SELECT <columns> from inserted[/code]

    Try using that kind of pattern. You shouldn't be assigning variables from inserted because the trigger will 'break' if there are multiple rows in the inserted table.

    The columns you want to use in the select portion of the insert statement are the columns you want to log from the table being inserted into (you said customerID and Email)

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • My problem is I don't know what physical code to type in on the values line.

    INSERT INTO CustomerLog (CustomerLogId, CustomerID, Email, LogDate)

    Values(CustomerLogId, @CustomerID, Email, GetDate())

    When I enter the preceding code in, and attempt to execute it, I get the following error:

    Msg 128, Level 15, State 1, Procedure tgrCustomerInsert, Line 8

    The name "CustomerLogId" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.

    I don't know what to put instead of CustomerLogId or Email in the values line.

  • Please look at the rough code I gave you. I didn't use Insert .. values anywhere.

    If you are writing a trigger to log inserted rows into another table you cannot use Insert ... values as it will give incorrect results when there are multiple rows. That's why I wrote you some pseudocode to use.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Thanks but unfortunately I'm either not smart enough to figure that out or it's just not creating what I need it to. My assignment was to only passthrough the CustomerID from the Customer database and all the remaining information would come in.

    I guess thats why i'm just a beginner.

  • Which part of the rough sample code that I posted don't you understand?

    Forget about passing customerIDs around, that's not how triggers work. The rough code I posted would be the entirety of the trigger, no other selects, no inserts, no variables. Just a single insert statement

    Edit: And maybe have a quick read up in books Online (the SQL help file) about triggers.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • I guess the rough part now is passing the ID in is how I was instructed specifically to create the trigger.

    I'll take a look at the books.

    Thanks.

  • Well you can't pass an ID to a trigger, and pulling an ID out of the inserted table into a variable is a common error when writing triggers as if results in incorrect behaviour when multiple rows are in the inserted table (as in a multi-row insert). That's why the rough code I gave does not do that.

    So, to repeat, a trigger that fires after insert to a specific table and inserts some of the just-inserted values into another table generally looks like this:

    CREATE TRIGGER <trigger name here>

    ON <table that is being inserted into>

    AFTER INSERT

    AS

    Insert Into <Logging table name> (<columns in the logging table>)

    SELECT <matching columns from the table being inserted into>

    FROM inserted

    -- end of trigger

    GO

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Maybe it shouldn't be an insert then, an update trigger instead. Attached is my specifics.

  • If the trigger needs to fire after a row is added to customer, it's an insert trigger, if fires after an insert operation. An update trigger fires after a row is modified by an UPDATE statement.

    Besides, everything I've said is relevant to update triggers as well.

    p.s. That exercise looks like homework, which means I am not going to do it for you. I'll advise, but that's all.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Yes, this is homework. And unfortunately, it's easy to see that I didn't understand my one example given.

    Not looking for the answers, I want to figure this out myself, as i'm sure it'll be prevalent in future assignments.

    I'm just trying to decipher between the example I was given (following) and your examples.

    -- INSERT TRIGGER

    Create Table AddLog (TableName varchar(30), AddDate datetime,

    Name varchar(50))

    CREATE TRIGGER tgrTableInsert ON TableA FOR INSERT

    AS

    DECLARE @TheName varchar(50)

    Select @TheName = Name From inserted

    INSERT INTO AddLog (TableName, AddDate, Name)

    Values('TableA', GetDate(), @TheName )

    GO

    Insert Into TableA (Id,Name) Values(11,'Grape')

    Select * From AddLog

  • User ZIYkkE22ol has been reported.



    Posting Data Etiquette - Jeff Moden[/url]
    Posting Performance Based Questions - Gail Shaw[/url]
    Hidden RBAR - Jeff Moden[/url]
    Cross Tabs and Pivots - Jeff Moden[/url]
    Catch-all queries - Gail Shaw[/url]


    If you don't have time to do it right, when will you have time to do it over?

  • Now that you've explained that this is for study purposes, we'll be able to give you the information on a level that you will be able to understand.

    You'll have to look up the information on the T-SQL "insert" statement to see Gail's point. Your best reference for Microsoft SQL server is Microsoft's web site called Books Online (often refered to as BOL). The information for the insert statement can be found here: http://msdn.microsoft.com/en-US/library/ms174335(v=sql.105).aspx.

    You are likely only used to see:

    insert (col1, col2)

    values ( 'val1', 'val2') .

    The far more often used syntax is however:

    insert (col1, col2)

    select 'val1', 'val2'

    The difference being as Gail was trying to explain, that the values()-variant only works for a single row of data, whereas the select-variant may insert virtually any number of rows in a single statement.

    edit: While re-reading my examples I saw that I made some serious errors in them, that will not help you in getting the idea. So I have replaced them with some better ones:

    insert using values() as in your example:

    DECLARE @TheName varchar(50)

    Select @TheName = Name From inserted

    INSERT INTO AddLog (TableName, AddDate, Name)

    Values('TableA', GetDate(), @TheName )

    And the way it should have been presented, using the insert-select syntax:

    INSERT INTO AddLog (TableName, AddDate, Name)

    select 'TableA', GetDate(), i.Name

    from inserted i



    Posting Data Etiquette - Jeff Moden[/url]
    Posting Performance Based Questions - Gail Shaw[/url]
    Hidden RBAR - Jeff Moden[/url]
    Cross Tabs and Pivots - Jeff Moden[/url]
    Catch-all queries - Gail Shaw[/url]


    If you don't have time to do it right, when will you have time to do it over?

Viewing 15 posts - 1 through 15 (of 16 total)

You must be logged in to reply to this topic. Login to reply