Solved

The Oracle triggers

Posted on 2014-01-29
8
434 Views
Last Modified: 2014-03-02
Right now we are doing BEFORE delete/AFTER INSERT/AFTER update trigger for any Oralce DB, the MySQL one has been done:

 DROP TRIGGER IF EXISTS PACKAGE_ELEMENT_BEFORE_DELETE_TRIGGER; CREATE TRIGGER PACKAGE_ELEMENT_BEFORE_DELETE_TRIGGER BEFORE DELETE ON PACKAGE_ELEMENT FOR EACH ROW BEGIN  INSERT INTO Audit_info.PCCWSP_DBAudit_PACKAGE_ELEMENT SET  TriggerAction="BEFORE", ActionDone="DELETE", ActionDate=now(), ActionBy=USER() , PACKAGE_ID=OLD.PACKAGE_ID, ELEMENT_ID=OLD.ELEMENT_ID, PRODUCT_FAMILY=OLD.PRODUCT_FAMILY, PRODUCT_TYPE=OLD.PRODUCT_TYPE, VENDOR_TYPE=OLD.VENDOR_TYPE, VENDOR_ID=OLD.VENDOR_ID, ITEM_CATEGORY=OLD.ITEM_CATEGORY, ITEM_SUBCATEGORY=OLD.ITEM_SUBCATEGORY, NOMENCLATURE=OLD.NOMENCLATURE, FROM_COUNTRY=OLD.FROM_COUNTRY, FROM_CITY=OLD.FROM_CITY, FROM_POP_ID=OLD.FROM_POP_ID, TO_COUNTRY=OLD.TO_COUNTRY, TO_CITY=OLD.TO_CITY, TO_POP_ID=OLD.TO_POP_ID, FROM_SITE_TYPE=OLD.FROM_SITE_TYPE, TO_SITE_TYPE=OLD.TO_SITE_TYPE, FROM_BANDWIDTH=OLD.FROM_BANDWIDTH, FROM_BW_UNIT=OLD.FROM_BW_UNIT, TO_BANDWIDTH=OLD.TO_BANDWIDTH, TO_BW_UNIT=OLD.TO_BW_UNIT, PARTNERSHIP_MODEL=OLD.PARTNERSHIP_MODEL, PROTECTION=OLD.PROTECTION, RESTORABLE=OLD.RESTORABLE, CREATED_DT=OLD.CREATED_DT, CREATED_BY=OLD.CREATED_BY, UPDATED_DT=OLD.UPDATED_DT, UPDATED_BY=OLD.UPDATED_BY, AAA=OLD.AAA, AAB=OLD.AAB; END ; 

Open in new window


what should be the correct version for Oracle 10g and 11g ?
0
Comment
Question by:marrowyung
  • 3
  • 2
8 Comments
 
LVL 37

Assisted Solution

by:Geert Gruwez
Geert Gruwez earned 200 total points
ID: 39820261
in oracle you can use "create or replace"
if the trigger exists, it will replace the existing one, if not, it will create it
CREATE OR REPLACE TRIGGER PACKAGE_ELEMENT_BEFORE_DELETE_TRIGGER 
BEFORE DELETE ON PACKAGE_ELEMENT 
FOR EACH ROW 
BEGIN  
  INSERT INTO Audit_info.PCCWSP_DBAudit_PACKAGE_ELEMENT 
  SET  TriggerAction="BEFORE", ActionDone="DELETE", ActionDate=SYSDATE, 
    ActionBy=USER , PACKAGE_ID=:OLD.PACKAGE_ID, 
    ELEMENT_ID=:OLD.ELEMENT_ID, 
    PRODUCT_FAMILY=:OLD.PRODUCT_FAMILY, 
    PRODUCT_TYPE=:OLD.PRODUCT_TYPE, 
    etc ... etc ...
END ;

Open in new window

0
 
LVL 73

Expert Comment

by:sdstuber
ID: 39820611
In oracle you can do delete, insert and update all in one trigger.
But change the BEFORE DELETE to AFTER DELETE (it shouldn't matter)

The INSERT syntax is different in Oracle, you don't use SET

CREATE TRIGGER trg_package_element_ariud
    AFTER DELETE OR INSERT OR UPDATE
    ON package_element
    FOR EACH ROW
BEGIN
    INSERT INTO audit_info.pccwsp_dbaudit_package_element(
                    triggeraction,
                    actiondone,
                    actiondate,
                    actionby,
                    package_id,
                    element_id,
                    product_family,
                    product_type,
                    vendor_type,
                    vendor_id,
                    item_category,
                    item_subcategory,
                    nomenclature,
                    from_country,
                    from_city,
                    from_pop_id,
                    to_country,
                    to_city,
                    to_pop_id,
                    from_site_type,
                    to_site_type,
                    from_bandwidth,
                    from_bw_unit,
                    to_bandwidth,
                    to_bw_unit,
                    partnership_model,
                    protection,
                    restorable,
                    created_dt,
                    created_by,
                    updated_dt,
                    updated_by,
                    aaa,
                    aab
                )
         VALUES (
                    'AFTER',
                    CASE
                            WHEN INSERTING THEN 'INSERT'
                            WHEN UPDATING THEN 'UPDATE'
                            ELSE 'DELETE'
                        END,
                    SYSDATE,
                    USER,
                    :old.package_id,
                    :old.element_id,
                    :old.product_family,
                    :old.product_type,
                    :old.vendor_type,
                    :old.vendor_id,
                    :old.item_category,
                    :old.item_subcategory,
                    :old.nomenclature,
                    :old.from_country,
                    :old.from_city,
                    :old.from_pop_id,
                    :old.to_country,
                    :old.to_city,
                    :old.to_pop_id,
                    :old.from_site_type,
                    :old.to_site_type,
                    :old.from_bandwidth,
                    :old.from_bw_unit,
                    :old.to_bandwidth,
                    :old.to_bw_unit,
                    :old.partnership_model,
                    :old.protection,
                    :old.restorable,
                    :old.created_dt,
                    :old.created_by,
                    :old.updated_dt,
                    :old.updated_by,
                    :old.aaa,
                    :old.aab
                );
END;
0
 
LVL 1

Author Comment

by:marrowyung
ID: 39832730
sdstuber,

"But change the BEFORE DELETE to AFTER DELETE "

so there are no before delete ?

Also in MySQL, I use the following function to dynamically generate the BEFORE DELETE trigger statement:

CREATE FUNCTION `Function_Create_BEFORE_DELETE_TRIGGER` (Trigger_databasename VARCHAR(40),  trigger_tablename VARCHAR(40))  	
RETURNS TEXT
NOT DETERMINISTIC      
READS SQL DATA
BEGIN  
DECLARE a, b, fieldnameCursor_finished  INT DEFAULT 10;
DECLARE temptable VARCHAR(50);	
DECLARE today TIMESTAMP DEFAULT CURRENT_DATE;
DECLARE v1, v2, v3 TINYINT ;
DECLARE current_fieldname  VARCHAR(50) DEFAULT ""; 
/* DECLARE fullexcutecmd VARCHAR(65535);
DECLARE fullexcutecmd1 VARCHAR(5000);
DECLARE fullexcutecmd2 VARCHAR(5000);
DECLARE fullexcutecmd3 VARCHAR(60000);*/
DECLARE fullexcutecmd TEXT;
DECLARE fullexcutecmd1 TEXT;
DECLARE fullexcutecmd2 TEXT;
DECLARE fullexcutecmd3 TEXT;

/*Declare and populate the cursor with a SELECT statement */  	
	  
DECLARE fieldname CURSOR FOR 	
SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_SCHEMA = Trigger_databasename AND TABLE_NAME = trigger_tablename ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET fieldnameCursor_finished = 1;     

  
SET @fullexcutecmd1= CONCAT( '  DROP TRIGGER IF EXISTS ',trigger_tablename,'_BEFORE_DELETE_TRIGGER; CREATE TRIGGER ',trigger_tablename,'_BEFORE_DELETE_TRIGGER BEFORE DELETE ON ',trigger_tablename,' FOR EACH ROW
BEGIN 
INSERT INTO Audit_info.',Trigger_databasename,'_DBAudit_',trigger_tablename,' SET 
TriggerAction=','"','BEFORE','",','
ActionDone=','"','DELETE','",','
ActionDate=now(),
ActionBy=USER()');   

OPEN fieldname ;	

set @fullexcutecmd2=' ';
set @fullexcutecmd3=' ';

	get_fieldlist: LOOP	
 
   FETCH fieldname INTO current_fieldname;	
         IF fieldnameCursor_finished = 1 THEN 	
          LEAVE get_fieldlist;	
          END IF;	
 
SET @fullexcutecmd2 = CONCAT(' ',current_fieldname,'=OLD.',current_fieldname);
 set @fullexcutecmd3= CONCAT(@fullexcutecmd3,',',@fullexcutecmd2); 

      END LOOP  get_fieldlist;	
close fieldname;                             
  
  set @fullexcutecmd3= CONCAT(@fullexcutecmd1,@fullexcutecmd3,'; END ;'); 

  
END $$
DELIMITER ; 

Open in new window


is there anyway for Oracle to get dynamic SQL statement to construct that AFTER/BEFORE DELETE trigger?

Can it automatically execute as MySQL can't execute that create trigger statements itself.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 1

Author Comment

by:marrowyung
ID: 39846588
sdstuber,

"AFTER DELETE OR INSERT OR UPDATE"

So this mean we are now doing AFTRE delete/insert/update for this trigger? but we can't just do "BFFOR DELETE OR INSERT OR UPDATE" at the same time ?
0
 
LVL 73

Accepted Solution

by:
sdstuber earned 300 total points
ID: 39878439
>>> So this mean we are now doing AFTRE delete/insert/update for this trigger? but we can't just do "BFFOR DELETE OR INSERT OR UPDATE" at the same time ?

no, a trigger is either BEFORE or AFTER an event.

Based on your examples and descriptions above it makes the most sense to just use a single AFTER trigger.

This avoids complications with statement restart or rollbacks for mid statement failures.
0
 
LVL 1

Author Comment

by:marrowyung
ID: 39898663
"no, a trigger is either BEFORE or AFTER an event."

you just mean the trigger BELETE, INSERT and after can conbine in one trigger statement but just BEFORE or AFTER, right?
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
Read about achieving the basic levels of HRIS security in the workplace.
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
Via a live example, show how to take different types of Oracle backups using RMAN.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now