Create Trigger

download Create Trigger

of 7

Transcript of Create Trigger

  • 7/28/2019 Create Trigger

    1/7

  • 7/28/2019 Create Trigger

    2/7

    WITH APPEND cannot be used with INSTEAD OF triggers or if AFTER trigger is explicitly stated. WITH APPEND can beused only when FOR is specified (without INSTEAD OF or AFTER) for backward compatibility reasons. WITH APPEND andFOR (which is interpreted as AFTER) will not be supported in future releases.

    NOT FOR REPLICATIONIndicates that the trigger should not be executed when a replication process modifies the table involved in the trigger.ASAre the actions the trigger is to perform.

    sql_statementIs the trigger condition(s) and action(s). Trigger conditions specify additional criteria that determine whether the attempted

    DELETE, INSERT, or UPDATE statements cause the trigger action(s) to be carried out.The trigger actions specified in the Transact-SQL statements go into effect when the DELETE, INSERT, or UPDATE operationis attempted.

    Triggers can include any number and kind of Transact-SQL statements. A trigger is designed to check or change data based on adata modification statement; it should not return data to the user. The Transact-SQL statements in a trigger often include control-of-flow language. A few special tables are used in CREATE TRIGGER statements:

    deleted and inserted are logical (conceptual) tables. They are structurally similar to the table on which the trigger isdefined, that is, the table on which the user action is attempted, and hold the old values or new values of the rows thatmay be changed by the user action. For example, to retrieve all values in the deleted table, use:

    SELECT * FROM deleted In a DELETE, INSERT, or UPDATE trigger, SQL Server does not allow text, ntext, orimage column references in

    the inserted and deleted tables if the compatibility level is equal to 70. The text, ntext, and image values in theinserted and deleted tables cannot be accessed. To retrieve the new value in either an INSERT or UPDATE trigger,join the inserted table with the original update table. When the compatibility level is 65 or lower, null values arereturned forinserted ordeletedtext, ntext, orimage columns that allow null values; zero-length strings are returned if

    the columns are not nullable.If the compatibility level is 80 or higher, SQL Server allows the update oftext, ntext, orimage columns through theINSTEAD OF trigger on tables or views.

    nIs a placeholder indicating that multiple Transact-SQL statements can be included in the trigger. For the IF UPDATE (column)

    statement, multiple columns can be included by repeating the UPDATE (column) clause.IF UPDATE (column)Tests for an INSERT or UPDATE action to a specified column and is not used with DELETE operations. More than one column

    can be specified. Because the table name is specified in the ON clause, do not include the table name before the column name inan IF UPDATE clause. To test for an INSERT or UPDATE action for more than one column, specify a separateUPDATE(column) clause following the first one. IF UPDATE will return the TRUE value in INSERT actions because the

    columns have either explicit values or implicit (NULL) values inserted.Note The IF UPDATE (column) clause functions identically to an IF, IF...ELSE or WHILE statement and can use theBEGIN...END block. For more information, seeControl-of-Flow Language.UPDATE(column) can be used anywhere inside the body of the trigger.column

    Is the name of the column to test for either an INSERT or UPDATE action. This column can be of any data type supported bySQL Server. However, computed columns cannot be used in this context. For more information, seeData Types.IF (COLUMNS_UPDATED())

    Tests, in an INSERT or UPDATE trigger only, whether the mentioned column or columns were inserted or updated.

    COLUMNS_UPDATED returns a varbinary bit pattern that indicates which columns in the table were inserted or updated.The COLUMNS_UPDATED function returns the bits in order from left to right, with the least significant bit being the leftmost.The leftmost bit represents the first column in the table; the next bit to the right represents the second column, and so on.COLUMNS_UPDATED returns multiple bytes if the table on which the trigger is created contains more than 8 columns, with the

    least significant byte being the leftmost. COLUMNS_UPDATED will return the TRUE value for all columns in INSERT actionsbecause the columns have either explicit values or implicit (NULL) values inserted.

    COLUMNS_UPDATED can be used anywhere inside the body of the trigger.bitwise_operatorIs the bitwise operator to use in the comparison.

    updated_bitmaskIs the integer bitmask of those columns actually updated or inserted. For example, table t1 contains columns C1, C2, C3, C4, andC5. To check whether columns C2, C3, and C4 are all updated (with table t1 having an UPDATE trigger), specify a value of 14.To check whether only column C2 is updated, specify a value of 2.

    comparison_operatorIs the comparison operator. Use the equal sign (=) to check whether all columns specified in updated_bitmaskare actuallyupdated. Use the greater than symbol (>) to check whether any or some of the columns specified in updated_bitmaskare updated.

    http://msdn.microsoft.com/en-us/library/aa226017%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa226017%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa226017%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa258271%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa258271%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa258271%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa258271%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa226017%28v=sql.80%29.aspx
  • 7/28/2019 Create Trigger

    3/7

    column_bitmaskIs the integer bitmask of those columns to check whether they are updated or inserted.Remarks

    Triggers are often used for enforcing business rules and data integrity. SQL Server provides declarative referential integrity(DRI) through the table creation statements (ALTER TABLE and CREATE TABLE); however, DRI does not provide cross-database referential integrity. To enforce referential integrity (rules about the relationships between the primary and foreign keysof tables), use primary and foreign key constraints (the PRIMARY KEY and FOREIGN KEY keywords of ALTER TABLE and

    CREATE TABLE). If constraints exist on the trigger table, they are checked after the INSTEAD OF trigger execution and priorto the AFTER trigger execution. If the constraints are violated, the INSTEAD OF trigger actions are rolled back and the AFTERtrigger is not executed (fired).The first and last AFTER triggers to be executed on a table may be specified by using sp_settriggerorder. Only one first and one

    last AFTER trigger for each of the INSERT, UPDATE, and DELETE operations may be specified on a table; if there are otherAFTER triggers on the same table, they are executed randomly.If an ALTER TRIGGER statement changes a first or last trigger, the first or last attribute set on the modified trigger is dropped,and the order value must be reset with sp_settriggerorder.An AFTER trigger is executed only after the triggering SQL statement, including all referential cascade actions and constraint

    checks associated with the object updated or deleted, has executed successfully. The AFTER trigger sees the effects of thetriggering statement as well as all referential cascade UPDATE and DELETE actions caused by the triggering statement.If an INSTEAD OF trigger defined on a table executes a statement against the table that would usually fire the INSTEAD OFtrigger again, the trigger is not called recursively. Instead, the statement is processed as if the table had no INSTEAD OF trigger

    and starts the chain of constraint operations and AFTER trigger executions. For example, if a trigger is defined as an INSTEADOF INSERT trigger for a table, and the trigger executes an INSERT statement on the same table, the INSERT statement executed

    by the INSTEAD OF trigger does not call the trigger again. The INSERT executed by the trigger starts the process of performingconstraint actions and firing any AFTER INSERT triggers defined for the table.

    If an INSTEAD OF trigger defined on a view executes a statement against the view that would usually fire the INSTEAD OFtrigger again, it is not called recursively. Instead, the statement is resolved as modifications against the base tables underlying theview. In this case, the view definition must meet all of the restrictions for an updatable view. For a definition of updatable views,seeModifying Data Through a View. For example, if a trigger is defined as an INSTEAD OF UPDATE trigger for a view, and

    the trigger executes an UPDATE statement referencing the same view, the UPDATE statement executed by the INSTEAD OFtrigger does not call the trigger again. The UPDATE executed by the trigger is processed against the view as if the view did nothave an INSTEAD OF trigger. The columns changed by the UPDATE must be resolved to a s ingle base table. Each modificationto an underlying base table starts the chain of applying constraints and firing AFTER triggers defined for the table.Trigger Limitations

    CREATE TRIGGER must be the first statement in the batch and can apply to only one table.

    A trigger is created only in the current database; however, a trigger can reference objects outside the current database.If the trigger owner name is specified (to qualify the trigger), qualify the table name in the same way.The same trigger action can be defined for more than one user action (for example, INSERT and UPDATE) in the same

    CREATE TRIGGER statement.INSTEAD OF DELETE/UPDATE triggers cannot be defined on a table that has a foreign key with a cascade onDELETE/UPDATE action defined.Any SET statement can be specified inside a trigger. The SET option chosen remains in effect during the execution of the trigger

    and then reverts to its former setting.When a trigger fires, results are returned to the calling application, just as with stored procedures. To eliminate having resultsreturned to an application due to a trigger firing, do not include either SELECT statements that return results, or statements that

    perform variable assignment in a trigger. A trigger that includes either SELECT statements that return results to the user or

    statements that perform variable assignment requires special handling; these returned results would have to be written into everyapplication in which modifications to the trigger table are allowed. If variable assignment must occur in a trigger, use a SET

    NOCOUNT statement at the beginning of the trigger to eliminate the return of any result sets.A TRUNCATE TABLE statement is not caught by a DELETE trigger. Although a TRUNCATE TABLE statement is, in effect, a

    DELETE without a WHERE clause (it removes all rows), it is not logged and thus cannot execute a trigger. Because permissionfor the TRUNCATE TABLE statement defaults to the table owner and is not transferable, only the table owner should beconcerned about inadvertently circumventing a DELETE trigger with a TRUNCATE TABLE statement.

    The WRITETEXT statement, whether logged or unlogged, does not activate a trigger.These Transact-SQL statements are not allowed in a trigger:

    ALTER DATABASE CREATE DATABASE DISK INIT

    DISK RESIZE DROP DATABASE LOAD DATABASE

    LOAD LOG RECONFIGURE RESTORE DATABASE

    RESTORE LOG

    Note Because SQL Server does not support user-defined triggers on system tables, it is recommended that no user-definedtriggers be created on system tables.

    http://msdn.microsoft.com/en-us/library/aa933146%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa933146%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa933146%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa933146%28v=sql.80%29.aspx
  • 7/28/2019 Create Trigger

    4/7

    Multiple Triggers

    SQL Server allows multiple triggers to be created for each data modification event (DELETE, INSERT, or UPDATE). Forexample, if CREATE TRIGGER FOR UPDATE is executed for a table that already has an UPDATE trigger, then an additional

    update trigger is created. In earlier versions, only one trigger for each data modification event (INSERT, UPDATE, DELETE)was allowed for each table.Note The default behavior for CREATE TRIGGER (with the compatibility level of 70) is to add additional triggers to existingtriggers, if the trigger names differ. If trigger names are the same, SQL Server returns an error message. However, if the

    compatibility level is equal to or less than 65, any new triggers created with the CREATE TRIGGER statement replace any

    existing triggers of the same type, even if the trigger names are different. For more information, seesp_dbcmptlevel.Recursive Triggers

    SQL Server also allows recursive invocation of triggers when the recursive triggers setting is enabled in sp_dboption.Recursive triggers allow two types of recursion to occur:

    Indirect recursion Direct recursion

    With indirect recursion, an application updates table T1, which fires triggerTR1, updating table T2. In this scenario, triggerT2then fires and updates table T1.With direct recursion, the application updates table T1, which fires triggerTR1, updating table T1. Because table T1 was

    updated, triggerTR1 fires again, and so on.

    This example uses both indirect and direct trigger recursion. Assume that two update triggers, TR1 and TR2, are defined on tableT1. TriggerTR1 updates table T1 recursively. An UPDATE statement executes each TR1 and TR2 one time. In addition, theexecution ofTR1 triggers the execution ofTR1 (recursively) and TR2. The inserted and deletedtables for a given triggercontain rows corresponding only to the UPDATE statement that invoked the trigger.Note The above behavior occurs only if the recursive triggers setting ofsp_dboption is enabled. There is no defined order in

    which multiple triggers defined for a given event are executed. Each trigger should be self-contained.Disabling the recursive triggers setting only prevents direct recursions. To disable indirect recursion as well, set the nestedtriggers server option to 0 using sp_configure.

    If any of the triggers do a ROLLBACK TRANSACTION, regardless of the nesting level, no further triggers are executed.Nested Triggers

    Triggers can be nested to a maximum of 32 levels. If a trigger changes a table on which there is another trigger, the secondtrigger is activated and can then call a third trigger, and so on. If any trigger in the chain sets off an infinite loop, the nesting levelis exceeded and the trigger is canceled. To disable nested triggers, set the nested triggers option ofsp_configure to 0 (off). The

    default configuration allows nested triggers. If nested triggers is off, recursive triggers is also disabled, regardless of therecursive triggers setting ofsp_dboption.Deferred Name Resolution

    SQL Server allows Transact-SQL stored procedures, triggers, and batches to refer to tables that do not exist at compile time. This

    ability is called deferred name resolution. However, if the Transact-SQL stored procedure, trigger, or batch refers to a tabledefined in the stored procedure or trigger, a warning is issued at creation time only if the compatibility level setting (set byexecuting sp_dbcmptlevel) is equal to 65. A warning is issued at compile time if a batch is used. An error message is returned atrun time if the table referenced does not exist. For more information, seeDeferred Name Resolution and Compilation.Permissions

    CREATE TRIGGER permissions default to the table owner on which the trigger is defined, the sysadmin fixed server role, andmembers of the db_owner and db_ddladmin fixed database roles, and are not transferable.To retrieve data from a table or view, a user must have SELECT statement permission on the table or view. To update the contentof a table or view, a user must have INSERT, DELETE, and UPDATE statement permissions on the table or view.

    If an INSTEAD OF trigger exists on a view, the user must have INSERT, DELETE, and UPDATE privileges on that view toissue INSERT, DELETE, and UPDATE statements against the view, regardless of whether the execution actually performs suchan operation on the view.ExamplesA. Use a trigger with a reminder message

    This example trigger prints a message to the client when anyone tries to add or change data in the titles table.Note Message 50009 is a user-defined message in sysmessages. For more information about creating user-defined messages, seesp_addmessage.USE pubsIF EXISTS (SELECT name FROM sysobjects

    WHERE name = 'reminder' AND type = 'TR')

    DROP TRIGGER reminderGOCREATE TRIGGER reminderON titlesFOR INSERT, UPDATEAS RAISERROR (50009, 16, 10)GOB. Use a trigger with a reminder e-mail message

    This example sends an e-mail message to a specified person (MaryM) when the titles table changes.USE pubsIF EXISTS (SELECT name FROM sysobjects

    WHERE name = 'reminder' AND type = 'TR')DROP TRIGGER reminder

    GO

    http://msdn.microsoft.com/en-us/library/aa259649%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa259649%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa259649%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa214346%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa214346%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa214346%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa259591%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa259591%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa259591%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa214346%28v=sql.80%29.aspxhttp://msdn.microsoft.com/en-us/library/aa259649%28v=sql.80%29.aspx
  • 7/28/2019 Create Trigger

    5/7

    CREATE TRIGGER reminderON titlesFOR INSERT, UPDATE, DELETEAS

    EXEC master..xp_sendmail 'MaryM','Don''t forget to print a report for the distributors.'

    GOC. Use a trigger business rule between the employee and jobs tables

    Because CHECK constraints can reference only the columns on which the column- or table-level constraint is defined, any cross-

    table constraints (in this case, business rules) must be defined as triggers.This example creates a trigger that, when an employee job level is inserted or updated, checks that the specified employee joblevel (job_lvls), on which salaries are based, is within the range defined for the job. To get the appropriate range, thejobs table

    must be referenced.USE pubsIF EXISTS (SELECT name FROM sysobjects

    WHERE name = 'employee_insupd' AND type = 'TR')DROP TRIGGER employee_insupd

    GOCREATE TRIGGER employee_insupdON employeeFOR INSERT, UPDATEAS/* Get the range of level for this job type from the jobs table. */DECLARE @min_lvl tinyint,

    @max_lvl tinyint,@emp_lvl tinyint,@job_id smallint

    SELECT @min_lvl = min_lvl,

    @max_lvl = max_lvl,@emp_lvl = i.job_lvl,@job_id = i.job_id

    FROM employee e INNER JOIN inserted i ON e.emp_id = i.emp_idJOIN jobs j ON j.job_id = i.job_id

    IF (@job_id = 1) and (@emp_lvl 10)BEGIN

    RAISERROR ('Job id 1 expects the default level of 10.', 16, 1)ROLLBACK TRANSACTION

    ENDELSEIF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl)BEGIN

    RAISERROR ('The level for job_id:%d should be between %d and %d.',16, 1, @job_id, @min_lvl, @max_lvl)

    ROLLBACK TRANSACTIONENDD. Use deferred name resolution

    This example creates two triggers to illustrate deferred name resolution.

    USE pubsIF EXISTS (SELECT name FROM sysobjects

    WHERE name = 'trig1' AND type = 'TR')DROP TRIGGER trig1

    GO-- Creating a trigger on a nonexistent table.CREATE TRIGGER trig1on authorsFOR INSERT, UPDATE, DELETEAS

    SELECT a.au_lname, a.au_fname, x.infoFROM authors a INNER JOIN does_not_exist x

    ON a.au_id = x.au_idGO-- Here is the statement to actually see the text of the trigger.SELECT o.id, c.textFROM sysobjects o INNER JOIN syscomments c

    ON o.id = c.idWHERE o.type = 'TR' and o.name = 'trig1'

    -- Creating a trigger on an existing table, but with a nonexistent-- column.USE pubsIF EXISTS (SELECT name FROM sysobjects

    WHERE name = 'trig2' AND type = 'TR')DROP TRIGGER trig2

    GOCREATE TRIGGER trig2ON authorsFOR INSERT, UPDATEAS

    DECLARE @fax varchar(12)SELECT @fax = phone

  • 7/28/2019 Create Trigger

    6/7

  • 7/28/2019 Create Trigger

    7/7

    ins.emp_SSNFROM inserted ins

    ENDGO

    /*Inserting a new employee does not cause the UPDATE trigger to fire.*/INSERT INTO employeeData

    VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32)GO

    /*Updating the employee record for employee number 101 to change the salary to 51000 causes the UPDATE triggerto fire and an audit trail to be produced.*/

    UPDATE employeeDataSET emp_salary = 51000WHERE emp_id = 101

    GOSELECT * FROM auditEmployeeDataGO

    /*Updating the employee record for employee number 101 to change both the bank account number and socialsecurity number (SSN) causes the UPDATE trigger to fire and an audit trail to be produced.*/

    UPDATE employeeDataSET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'WHERE emp_id = 101

    GOSELECT * FROM auditEmployeeDataGO

    F. Use COLUMNS_UPDATED to test more than 8 columns

    If you must test for updates that affect columns other than the first 8 columns in a table, you must use the SUBSTRING function

    to test the proper bit returned by COLUMNS_UPDATED. This example tests for updates that affect columns 3, 5, or 9 in theNorthwind.dbo.Customers table.USE NorthwindDROP TRIGGER tr1GOCREATE TRIGGER tr1 ON CustomersFOR UPDATE AS

    IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))+ power(2,(5-1)))AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1))))

    PRINT 'Columns 3, 5 and 9 updated'GO

    UPDATE CustomersSET ContactName=ContactName,

    Address=Address,Country=Country

    GO