Triggers How triggers work Creating triggers Using triggers to maintain referential integrity Multirow considerations Nesting triggers Rules associated

  • View
    234

  • Download
    2

Embed Size (px)

Text of Triggers How triggers work Creating triggers Using triggers to maintain referential integrity...

Triggers

TriggersHow triggers workCreating triggersUsing triggers to maintain referential integrityMultirow considerationsNesting triggersRules associated with triggersDisabling triggersDropping triggersGetting information about triggersHow Triggers WorkA trigger is a stored procedure that goes into effect when you insert, delete, or update data in a table.You can use triggers to perform a number of automatic actions, such ascascading changesenforcing column restrictionscomparing the results of data modificationsmaintaining the referential integrity of data across a database.How Triggers WorkA trigger is specific to one or more of the data modification operations, update, insert, and delete and is executed once for each SQL statement.How Triggers WorkFor example, to prevent users from removing any publishing companies from the publishers table, you could use this trigger:create trigger del_pub on publishersfor deleteasbeginrollback transactionprint You cannot delete any publishers!endHow Triggers WorkA trigger fires only after the data modification statement has completed and Server has checked for any data type, rule, or integrity constraint violation.The trigger and the statement that fires it are treated as a single transaction that can be rolled back from within the trigger.If Server detects a severe error, the entire transaction is rolled back.How Triggers WorkTriggers are most useful in these situations:Triggers can cascade changes through related tables in the database.Triggers can disallow, or roll back, changes that would violate referential integrity, canceling the attempted data modification transaction.Triggers can enforce restrictions that are much more complex than those that are defined with rules.Triggers can perform simple what if analyses. For example, a trigger can compare the state of a table before and after a data modification and take action based on that comparison.Creating TriggersHere is the complete create trigger syntax:create trigger [owner.]trigger_nameon [owner.]table_name{for / instead of {insert , update , delete}as SQL_statementsOr, using the if update clause:create trigger [owner.]trigger_nameon [owner.]table_namefor {insert , update}as[if update (column_name )[{and | or} update (column_name )]...]SQL_statements[if update (column_name )[{and | or} update (column_name )]...SQL_statements ]...Creating TriggersSQL statements that are not allowed in triggers:

Since triggers execute as part of a transaction, the following statements are notallowed in a trigger: All create commands, including create database, create table, create index,create procedure, create default, create rule, create trigger, and create view All drop commands alter table and alter database truncate table grant and revoke update statistics reconfigure load database and load transaction disk init, disk mirror, disk refit, disk reinit, disk remirror, disk unmirror select intoTrigger Test TablesReferential integrity triggers keep the values of foreign keys in line with those in primary keys. When a data modification affects a key column, triggers compare the new column values to related keys by using temporary work tables called trigger test tables.When you write your triggers, you base your comparisons on the data that is temporarily stored in the trigger test tables.Trigger Test TablesServer uses two special tables in trigger statements: the deleted table and the inserted table. These are temporary tables used in trigger tests.The deleted table stores copies of the affected rows during delete and update statements. During the execution of a delete or update statement, rows are removed from the trigger table and transferred to the deleted table. The deleted and trigger tables ordinarily have no rows in common.Trigger Test TablesThe inserted table stores copies of the affected rows during insert and update statements. During an insert or an update, new rows are added to the inserted and trigger tables at the same time. The rows in inserted are copies of the new rows in the trigger table.An update is a delete followed by an insert; the old rows are copied to the deleted table first; then the new rows are copied to the trigger table and to the inserted table.

Insert Trigger ExampleWhen you insert a new foreign key row, make sure the foreign key matches a primary key. The trigger should check for joins between the inserted rows (using the inserted table) and the rows in the primary key table, and then roll back any inserts of foreign keys that do not match a key in the primary key table.The following trigger compares the title_id values from the inserted table with those from the titles table. It assumes that you are making an entry for the foreign key and that you are not inserting a null value. If the join fails, the transaction is rolled back.PUBS2 DB Schema

Insert Trigger Examplecreate trigger forinsertrig1on salesdetailfor insertasif (select count(*)from titles, insertedwhere titles.title_id = inserted.title_id) !=@@rowcount/* Cancel the insert and print a message.*/ beginrollback transactionprint No, the title_id does not exist in titles. end/* Otherwise, allow it. */elseprint Added! All title_ids exist in titles.Insert Trigger Example@@rowcount (Returns the number of rows affected by the last statement) refers to the number of rows added to the salesdetail table. This is also the number of rows added to the inserted table. The trigger joins titles and inserted to determine whether all the title_ids added to salesdetail exist in the titles table. If the number of joined rows, which is determined by the select count(*) query, differs from @@rowcount, then one or more of the inserts is incorrect, and the transaction is canceled.Insert Trigger ExampleThis trigger prints one message if the insert is rolled back and another if it is accepted. To test for the first condition, try this insert statement:insert salesdetailvalues ("7066", "234517", "TC9999", 70, 45)To test for the second condition, enter:insert salesdetailvalues ("7896", "234518", "TC3218", 75, 80)Delete Trigger ExampleWhen you delete a primary key row, delete corresponding foreign key rows in dependent tables. This preserves referential integrity by ensuring that detail rows are removed when their master row is deleted. If you do not delete the corresponding rows in the dependent tables, you may end up with a database with detail rows that cannot be retrieved or identified. To properly delete the dependent foreign key rows, use a trigger that performs a cascading delete.Cascading Delete ExampleWhen a delete statement on titles is executed, one or more rows leave the titles table and are added to deleted. A trigger can check the dependent tablestitleauthor, salesdetail, and royschedto see if they have any rows with a title_id that matches the title_ids removed from titles and is now stored in the deleted table. If the trigger finds any such rows, it removes them.Cascading Delete Examplecreate trigger delcascadetrigon titlesfor deleteasdelete titleauthorfrom titleauthor, deletedwhere titleauthor.title_id = deleted.title_id/* Remove titleauthor rows that match deleted (titles) rows.*/delete salesdetailfrom salesdetail, deletedwhere salesdetail.title_id = deleted.title_id/* Remove salesdetail rows that match deleted ** (titles) rows.*/delete royschedfrom roysched, deletedwhere roysched.title_id = deleted.title_id/* Remove roysched rows that match deleted** (titles) rows.*/Restricted Delete ExamplesIn practice, you may want to keep some of the detail rows, either for historical purposes (to check how many sales were made on discontinued titles while they were active) or because transactions on the detail rows are not yet complete. A well-written trigger should take these factors into consideration.Restricted Delete ExamplesPreventing primary key deletionsThe deltitle trigger prevents the deletion of a primary key if there are any detail rows for that key in the salesdetail table. This trigger preserves the ability to retrieve rows from salesdetail:create trigger deltitleon titlesfor deleteasif (select count(*)from deleted, salesdetailwhere salesdetail.title_id =deleted.title_id) > 0 beginrollback transactionprint You cannot delete a title with sales. end

In this trigger, the row or rows deleted from titles are tested by being joinedwith the salesdetail table. If a join is found, the transaction is canceled.Restricted Delete ExamplesRecording errors that occurThe following restricted delete prevents deletes if the primary table, titles, has dependent children in titleauthor. Instead of counting the rows from deleted and titleauthor, it checks to see if title_id was deleted. This method is more efficient for performance reasons because it checks for the existence of a particular row rather than going through the entire table and counting all the rows:create trigger restrict_dtrig on titlesfor delete asif exists (select * from titleauthor, deleted where titleauthor.title_id = deleted.title_id)beginrollback transactionraiserror 35003returnendTo test this trigger, try this delete statement:delete titleswhere title_id = PS2091Update Trigger ExamplesThe following example cascades an update from the primary table titles to the dependent tables titleauthor and roysched.create trigger cascade_utrigon titlesfor update asif update(title_id)beginupdate titleauthorset title_id = inserted.title_id from titleauthor, deleted, insertedwhere deleted.title_id = titleauthor.title_idupdate royschedset title_id = inserted.title_id from roysched, deleted, insertedwhere deleted.title_id = roysched.title_idupdate salesdetailset title_id = inserted.title_id from salesdetail, deleted, insertedwhere deleted.title_id = salesdetail.title_idendUpdate Trigger ExamplesTo test this trigger, suppose that the book Secrets of Silicon Valley was reclassified to a psychology book from popular_comp. The following query updates the title_id