tearadta

Upload: karthikre

Post on 03-Jun-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/12/2019 Tearadta

    1/10

    Teradata Learning - Triggers (02/17/2013)

    A trigger is a event driven operationthat is caused by modification of one or more columnsof a row in a table.

    Note that the original modification request , the trigger and any other subsequenttriggers constitute a single transaction.

    Triggers can be particularly useful when Referential Integrity (RI) is defined. Triggers can beestablished to implement either the Cascade or Nullify strategies.

    Object type 'G'in HELP database output means a trigger. What is a triggering statement:

    Its the users SQL that a row to change in the table and causes the trigger to Execute.A triggering statement can be : INSERT, UPDATE,DELETE,INSERT/SELECTA triggering statement cannot be : SELECT.( A select Query cannot cause a trigger toexecute)

    What is a triggered statement:It's the SQL that gets executed as a result of triggering statement.A triggered statement can be

    : INSERT,DELETE,UPDATE,INSERT/SELECT,ABORT/ROLLBACK or EXEC(for macros)A triggered statement cannot be : BEGIN/END Transaction,

    COMMIT,CHECKPOINT,SELECTABORT/ROLLBACK can be triggered statement, but COMMIT and CHECKPOINT is not.

    Create Trigger Syntax:A trigger can be a Row Trigger or Statement trigger.Row Trigger:

    a. The row type trigger can fire multiple times for each triggering statement , once for everychanged row in the table.

    b. When using the Row type trigger , the REFERENCING statement provides name of the beforeimage of the row using via thephraseOLD AS,and after image of the row via thephrase NEW AS.

    c. Prior to Teradata V2R4, a row trigger could perform any valid DML statement except aSELECT.

    Since V2R4, it is a more ANSI standard implementation and can only perform an INSERT.

    In V2R6 a trigger may call a stored procedure.

    d. Basic format and syntax to create row trigger:CREATE TRIGGER {BEFORE | AFTER | INSTEAD OF} --> Trigger action[ ORDER ] --> Sequence of the trigger

  • 8/12/2019 Tearadta

    2/10

    {INSERT | UPDATE | DELETE | INSERT/SELECT} -->Triggering action[ OF (, ) ] ON --> specifies the column

    of subject table to be monitoredREFERENCING

    OLD AS --> before image of the rowNEW AS --> after image of the row

    FOR EACH ROW --> indicates that its a row type trigger[ WHEN (optional condition) ]

    ( { INSERT | INSERT/SELECT | UPDATE | DELETE } ;) --> Triggered action

    In the row trigger the triggered action shown is only INSERT and INSERT/SELECT.Try using DELETE AND UPDATE.Statement Trigger:

    a. Statement trigger will fire only once for each triggering statement.b. When using the STATEMENT type of trigger, the REFERENCING will use OLD_TABLE for

    all before image rows and NEW_TABLE for all after image rows.CREATE TRIGGER {BEFORE | AFTER | INSTEAD OF}[ ORDER ] {INSERT | UPDATE | DELETE | INSERT/SELECT}

    [ OF (, ) ] ON REFERENCING

    OLD_TABLE AS --> old tableNEW_TABLE AS --> New table

    FOR EACH STATEMENT --> Indicates that its a statement trigger[ WHEN (optional condition) ]

    ( { INSERT | INSERT/SELECT | UPDATE | DELETE |ABORT/ROLLBACK | EXEC } ; )

    ;EXEC is for calling a macro.Following is the meaning of each part of the TRIGGER syntax:

    BEFORE, AFTER, and INSTEAD OF.: The implication here regards when the triggerfires.

  • 8/12/2019 Tearadta

    3/10

    It either firesBEFORE the user request,AFTER the user requestorINSTEAD OF the user request.

    ORDER (optional):Used to sequence the firing of triggers. This is only a considerationwhen more than one trigger is based on the same trigger action(BEFORE, AFTER or

    INSTEAD OF). Triggering Statements: There are four types of SQL triggering statements that can

    cause a trigger to fire, they are: INSERT, INSERT/SELECT, UPDATE, and DELETE.When the triggering statement is an UPDATE, the optional OF portion is probably needed.Itnamesone or more specific column(s) to monitor for a change in the data.Note:When using multiple column names in the OF clause, If data in all columns named in

    the OF, is changed the trigger will fire. Otherwise, if the data is changed in only one of the

    columns, the trigger does not fire. It is all or nothing regarding the columns being monitoredfor a change.When the OF is not used,the value in every column must change in order for the

    trigger to fire. Subject Table:The table name specified by the ON is referred to as the subject table.

    Note : A trigger can only have one subject table. OLD AS, NEW AS:The OLD and NEW AS references can come together only when the

    triggering statement is an UPDATE. When triggering statement is UPDATE then only theBEFORE AND AFTER image makes sense.When the triggering statement is an INSERT, there is only a NEW AS reference name because

    there is only a new row and not an old row.

    Conversely, when the triggering statement is a DELETE, there is only an OLD AS reference

    name because the row no longer exists. WHEN clause:The optional WHEN designator provides a last conditional test to make before

    actuallyexecuting the trigger. Example: When you create a trigger to perform a specific action.

    However we may not want trigger to execute during the day time or if the data change is notmore than 10% . In such cases we use a WHEN clause which makes one final check beforeletting the trigger to execute.WHEN is the place where we can use SELECT in the subquery. Only place in trigger where

    SELECT is allowed. Triggered action: It is an SQL triggered statement that will execute as a result of the

    triggering statement.There are six SQL statements that can be a triggered statement, they are: INSERT,

    INSERT/SELECT, UPDATE, DELETE, EXEC and ABORT/ROLLBACK.

    Remember that a trigger is part of a transaction and cannot begin a new transaction. This is

    the reason why COMMIT is not allowed. The reason is that COMMIT will start a newtransaction.

  • 8/12/2019 Tearadta

    4/10

    BEFORE Trigger:The BEFORE trigger is executed prior to the maintenance requested by the users clientapplication. Once the trigger has successfully completed, the actual modification of the

    row(s) in the subject table is done for the user.Example of BEFORE trigger to apply RI.

    We create two tables as show below:CREATE MULTISET TABLE MY_TEST_DB.EMP_TABLE, NO FALLBACK(emp_no integer,dept_no integer,DW_LOAD_DTdate

    );CREATE MULTISET TABLE MY_TEST_DB.DEPT_TABLE, NO FALLBACK(dept_no integer,DW_LOAD_DT date

    );Then we executed the below trigger statement to create a trigger to insert a row todept_table before inserting it to emp_table.CREATE TRIGGER trigger1BEFORE INSERT on MY_TEST_DB.EMP_TABLEREFERENCING

    NEW AS newrow /*since trigger action is INSERT , we can only use NEW AS*/FOR EACH ROW(INSERT into MY_TEST_DB.DEPT_TABLE values (newrow.dept_no,date ););However this failed with the reason :CREATE TRIGGER Failed. 5424: A triggered action statement is the wrong

    kind.

    On investigating we found below information:The following are the valid triggered actions for the AFTER triggers:1. INSERT2. DELETE3. UPDATE4. ABORT5. EXEC macros containing any of the above statements.The following are the valid triggered actions for the BEFORE triggers:1. ABORT2. EXEC macros containing ABORT statements only.3. SET (only for BEFORE row triggers)Pasted from Thus as explained above we cannot use the triggered statement INSERT when trigger

    http://teradataerror.com/5424-A-triggered-action-statement-is-the-wrong-kind.htmlhttp://teradataerror.com/5424-A-triggered-action-statement-is-the-wrong-kind.htmlhttp://teradataerror.com/5424-A-triggered-action-statement-is-the-wrong-kind.htmlhttp://teradataerror.com/5424-A-triggered-action-statement-is-the-wrong-kind.html
  • 8/12/2019 Tearadta

    5/10

    action is BEFORE.Hence we inserted a row in dept_table with dept number 200.Now we create a row to abort a transaction of rows are inserted to employee table apartfrom dept no 200.CREATE TRIGGER MY_ONE_DAY_TABLES.trigger2BEFORE INSERT ON MY_TEST_DB.EMP_TABLEREFERENCING NEW ROW AS newrowFOR EACH ROWWHEN ( newrow.dept_no NOT IN (select dept_no from

    MY_TEST_DB.DEPT_TABLE))(ABORT;);Here the trigger is created under MY_ONE_DAY_TABLES database and tables are inMY_TEST_DB database.Hence there are chances that the insert will fail with below reason:

    INSERT Failed. 3523: An owner referenced by user does not have SELECTWITHGRANTOPTION access to MY_TEST_DB.EMP_TABLE.

    Here owner of the trigger is now MY_ONE_DAY_TABLES. Hence we grant the accessusing below queries. This may not be required on all systems.GRANT SELECT,INSERT,UPDATE on MY_TEST_DB.EMP_TABLE TO

    MY_ONE_DAY_TABLES WITH GRANT OPTION;GRANT SELECT,INSERT,UPDATE on MY_TEST_DB.DEPT_TABLE TOMY_ONE_DAY_TABLES WITH GRANT OPTION;Select * from MY_TEST_DB.DEPT_TABLE;dept_no DW_LOAD_DT200 2/16/2013insert into MY_TEST_DB.EMP_TABLE VALUES(2000,200,date); --> This worksfine with 1 row inserted.insert into MY_TEST_DB.EMP_TABLE VALUES(2000,300,date);--> This will not

    insert any rows and the dept value 300 is not in the dept_table.Thus now we know how to use BEFORE trigger.

    Note: We cannot drop the tables EMP_TABLE and DEPT_TABLE is there is a triggerdefined on the table.Other wise we would get following error message:Statement 1: DROP TABLE Failed. 5428: Table 'EMP_TABLE' has defined triggers.

    After Trigger:The AFTER trigger is executed or fired subsequent to the original update requested by the

    user's client application. Once the trigger has successfully completed, the user request partof the transaction is finished.

    In the below trigger a row will be inserted to DEPT_TABLE for every row being inserted

  • 8/12/2019 Tearadta

    6/10

    to EMP_TABLE.CREATE TRIGGER MY_ONE_DAY_TABLES.trigger1

    AFTER INSERT on MY_TEST_DB.EMP_TABLEREFERENCINGNEW AS newrowFOR EACH ROW(INSERT into MY_TEST_DB.DEPT_TABLE values (newrow.dept_no,date ););

    /* ; semil colon shoul be at the end of the triggered statement*/insert into MY_TEST_DB.EMP_TABLE values (100,200,date);

    select * from MY_TEST_DB.DEPT_TABLE;dept_no DW_LOAD_DT200 2/16/2013

    Update using triggerCREATE TRIGGER MY_ONE_DAY_TABLES.trigger1

    AFTER INSERT on MY_TEST_DB.EMP_TABLEREFERENCINGNEW AS newrowFOR EACH ROW(UPDATE MY_TEST_DB.DEPT_TABLE SET DW_LOAD_DT=newrow.DW_LOAD_DT- 1 where dept_no=newrow.dept_no ;);/* ; semil colon should be at the end of the triggered statement*/

    insert into MY_TEST_DB.EMP_TABLE values (1030,200,date);select * from MY_TEST_DB.DEPT_TABLEdept_no DW_LOAD_DT200 2/15/2013

    Statement Trigger:CREATE TABLE MY_TEST_DB.EMP_TABLE_2, NO FALLBACK ASMY_TEST_DB.EMP_TABLE WITH NO DATA AND STATSinsert into MY_TEST_DB.EMP_TABLE_2 values (100,1000,date);insert into MY_TEST_DB.EMP_TABLE_2 values (200,2000,date);insert into MY_TEST_DB.EMP_TABLE_2 values (300,3000,date);CREATE TRIGGER MY_ONE_DAY_TABLES.trigger1

    AFTER INSERT on MY_TEST_DB.EMP_TABLEREFERENCINGNEW TABLE AS newtable

  • 8/12/2019 Tearadta

    7/10

    FOR EACH STATEMENT(INSERT INTO MY_TEST_DB.DEPT_TABLE SELECT dept_no,date from

    newtable;);/* ; semil colon shoul be at the end of the triggered statement*/insert into MY_TEST_DB.EMP_TABLE select * from MY_TEST_DB.EMP_TABLE_2;

    select * from MY_TEST_DB.DEPT_TABLEdept_no DW_LOAD_DT1 2000 2/16/20132 1000 2/16/20133 3000 2/16/2013

    INSTEAD OF trigger:The INSTEAD OF trigger provides theabilityto execute the trigger and not do the users

    client application request at all.This is no longer valid as of V2R5.0.The following INSTEAD OF trigger is created on thepartstable to insert an audit rowinto the delay table indicating that an UPDATE on the parts table should have takenplace. However, because it was going to impact more than 10 rows in the subject table, itwas not performed:

    CREATE TRIGGER DelayUpdINSTEAD OF UPDATE OF (price) ON parts

    REFERENCING OLD_TABLE AS oldtab

    NEW_TABLE AS newtabFOR EACH STATEMENT

    WHEN ( 10 < (SELECT COUNT(part_num) FROM oldtab WHERE part_num =oldtab.part_num) )( INSERT INTO Delay_Tab

    SELECT DATE, TIME, 'Upd', newtab.part_num, newtab.priceFROM newtab WHERE newtab.part_num = part_num ; ) ;Note the way we find out the count of rows that are gonna get updated and then decide what

    should be done.

    Cascading Triggers:A cascading trigger results when a triggering statement fires a trigger, which in turnfires another trigger.The only thing a trigger cannot do is to change the subject table on which the trigger isdefined. However, a subsequent trigger may come back and update the original subject

    table. Caution should be exercised here so that the triggers do not cascade indefinitely. This

    constitutes an infinite loop and will cascade until they run out of either Permanent orTransient Journal space, or the transaction is aborted.

  • 8/12/2019 Tearadta

    8/10

    CREATE table MY_TEST_DB.REV_ADJ_CODEYELLOW, NO FALLBACK(amount decimal (10,2),datets timestamp

    );CREATE table MY_TEST_DB.REV_ADJ_CODEORANGE, NO FALLBACK(amount decimal (10,2),datets timestamp

    );CREATE table MY_TEST_DB.REV_ADJ_CODERED, NO FALLBACK(amount decimal (10,2),datets timestamp);Initially the adjustment amount is inserted into the CODEYELLOW Table.If this amount is more than Rs. 1000 then the trigger 'trigger1' gets executed and

    inserts row to CODEORANGE. If the amount is larger than 10000 the another trigger'trigger2' is executed which inserts rows in CODERED.CREATE TRIGGER MY_ONE_DAY_TABLES.Trigger1

    AFTER INSERT ON MY_TEST_DB.REV_ADJ_CODEYELLOWREFERENCING NEW AS new_rowFOR EACH ROWWHEN ( amount > 1000)

    (INSERT INTO MY_TEST_DB.REV_ADJ_CODEORANGE values(new_row.amount,current_timestamp););CREATE TRIGGER MY_ONE_DAY_TABLES.Trigger2

    AFTER INSERT ON MY_TEST_DB.REV_ADJ_CODEORANGEREFERENCING NEW AS new_rowFOR EACH ROWWHEN ( amount > 10000)(INSERT INTO MY_TEST_DB.REV_ADJ_CODERED values(new_row.amount,current_timestamp););GRANT SELECT,INSERT,UPDATE ON MY_TEST_DB.REV_ADJ_CODERED TO

    MY_ONE_DAY_TABLES WITH GRANT OPTION;GRANT SELECT,INSERT,UPDATE ON MY_TEST_DB.REV_ADJ_CODEORANGE TOMY_ONE_DAY_TABLES WITH GRANT OPTION;GRANT SELECT,INSERT,UPDATE ON MY_TEST_DB.REV_ADJ_CODEYELLOW TO

    MY_ONE_DAY_TABLES WITH GRANT OPTION;Then we perform inserts as below:insert into MY_TEST_DB.REV_ADJ_CODEYELLOW values (123.12,CURRENT_TIMESTAMP);insert into MY_TEST_DB.REV_ADJ_CODEYELLOW values (1234.12,CURRENT_TIMESTAMP);

  • 8/12/2019 Tearadta

    9/10

    insert into MY_TEST_DB.REV_ADJ_CODEYELLOW values (153.12,CURRENT_TIMESTAMP);insert into MY_TEST_DB.REV_ADJ_CODEYELLOW values (1213.12,CURRENT_TIMESTAMP);insert into MY_TEST_DB.REV_ADJ_CODEYELLOW values (121312.12,CURRENT_TIMESTAMP);And then check all the tables:SELECT * from MY_TEST_DB.REV_ADJ_CODEYELLOW;amount datets153.12 2/17/2013 00:49:52.720000121312.12 2/17/2013 00:49:54.2900001234.12 2/17/2013 00:49:51.920000123.12 2/17/2013 00:49:50.9500001213.12 2/17/2013 00:49:53.480000

    SELECT * from MY_TEST_DB.REV_ADJ_CODEORANGE;121312.12 2/17/2013 00:49:54.2900001234.12 2/17/2013 00:49:51.9200001213.12 2/17/2013 00:49:53.480000SELECT * from MY_TEST_DB.REV_ADJ_CODERED;Amount datets121312.12 2/17/2013 00:49:54.380000

    Sequencing Triggers:The ORDER option allows for the definition of a sequence number to beassociated witheach

    trigger. Valid values are 1 through 32,767.All triggers with an ORDER of 1, fire before the first ORDER 2 trigger. All the ORDER 2triggers fire before the first 3 and so on until there are no more triggers associated with the

    initial triggering statement.When ORDER is not specified, it defaults to a value of 32,767. Triggers with the same

    ORDERvalue fire randomly until the last one with that same value finishes.Example:As an example, instead of using the cascading triggers seen previously, it might bedesirable to have both triggers defined on CODEYELLOW

    CREATE TRIGGER MY_ONE_DAY_TABLES.Trigger1

    AFTER INSERT ON MY_TEST_DB.REV_ADJ_CODEYELLOW

    ORDER 100

    REFERENCING NEW AS new_row

  • 8/12/2019 Tearadta

    10/10

    FOR EACH ROW

    WHEN ( amount > 1000)

    (INSERT INTO MY_TEST_DB.REV_ADJ_CODEORANGE values

    (new_row.amount,current_timestamp););

    CREATE TRIGGER MY_ONE_DAY_TABLES.Trigger2

    AFTER INSERT ON MY_TEST_DB.REV_ADJ_CODEYELLOW

    ORDER 200

    REFERENCING NEW AS new_row

    FOR EACH ROW

    WHEN ( amount > 10000)

    (INSERT INTO MY_TEST_DB.REV_ADJ_CODERED values

    (new_row.amount,current_timestamp););

    Here two triggers with same trigger action on same table are defined.

    However we have assigned ORDER 100 to trigger1 and order 200 to trigger2.

    This will cause trigger1 to execute first and then trigger2.