Get Current SQL in Before delete trigger

Hi,
I have created a before delete trigger to track which records are deleted from a table I need to know what statements fires the trigger. can someone please describe how I can retrieve the current SQL.
using sys_context('userenv','CURRENT_SQL') returns null for CURRENT SQL
Note:
For me the easier is to enable auditing and audit delete on the table however at the moment I cant get a downtime from the business to bounce the database to enable auditing.
CREATE OR REPLACE TRIGGER before_delete BEFORE DELETE
ON AUDIT_TEST_TAB
FOR EACH ROW
DECLARE
v_username varchar2(50);
v_stmt varchar2(255);
v_client_info varchar2(200);
v_os_user varchar2(50);
v_machine varchar2(50);
v_program varchar2(50);
v_module varchar2(50);
v_auth_type varchar2(200);
v_ip_addr varchar2(200);
v_sql_statement VARCHAR2(4000);
BEGIN
SELECT sys_context ('USERENV', 'CURRENT_SQL')
INTO v_sql_statement
FROM dual;
-----------insert into logging table statment ----
end;

A few comments.
Lets assume you run a delete statement that deletes 550 rows from your table. If your trigger is working then the very same statement would be stored 550 times. I think an BEFORE or better an AFTER delete STATEMENT level trigger would be the better choice. Why AFTER? Because if the delete operation fails, for example because of existing child records, then everything is rolled back anyway to the implicit savepoint just before the delete.
So to store the SQL statement the correct trigger would be an AFTER STATEMENT DELETE trigger.
Now what to store: You want the sql statement. You could try to find the cursor/currently running SQL. It might be tricky to separate that from the SQLs that you run to find this out.
It could even be possible to simply save all commands that are in your PGA/Cached cursor area. First find out yur session, then store the SQL_text (first 60 chars) for all the cursors in this session by using v$open_cursor or the first 1000 chars by using v$sql.
Here are a few views that might be helpful. v$session , v$open_cursor, v$sql, v$sqltext, v$sql_bind_data, v$sql_bind_capture, dba_hist_sqltext

Similar Messages

  • Before delete trigger and foreign key relationship

    Hi,
    I am analysing one database for migration. On one parent table there is before delete trigger , to delete records from child. Also there is foreign key relationship on child table for this parent table.
    When I am deleting a row from parent, message gets displayed as "there are child records found."
    I would like to know, if there is foreign key relatioship then delete trigger on parent does't work, what is exactly happening?

    Could you post that trigger code and the Oracle version as well?
    With basic assumptions, I can't reproduce what you have stated here.
    Connected to:
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    SQL> create table parent (id number primary key);
    Table created.
    SQL> create table child (id number);
    Table created.
    SQL> alter table child add constraint fk_parent foreign key (id) references parent;
    Table altered.
    SQL> create or replace trigger bdr_parent
      2  before delete on parent
      3  for each row
      4  begin
      5  delete from child where id = :old.id;
      6  end;
      7  /
    Trigger created.
    SQL> insert into parent (id) values (1);
    1 row created.
    SQL> insert into child (id) values (1);
    1 row created.
    SQL> commit;
    Commit complete.
    SQL> delete from parent where id = 1;
    1 row deleted.
    SQL> select * from parent;
    no rows selected
    SQL> select * from child;
    no rows selected
    SQL> rollback;
    Rollback complete.
    SQL> alter table child drop constraint fk_parent;
    Table altered.
    SQL> alter table child add constraint fk_parent foreign key (id) references parent on delete cascade;
    Table altered.
    SQL> delete from parent where id = 1;
    delete from parent where id = 1
    ERROR at line 1:
    ORA-04091: table SCOTT.CHILD is mutating, trigger/function may not see it
    ORA-06512: at "SCOTT.BDR_PARENT", line 2
    ORA-04088: error during execution of trigger 'SCOTT.BDR_PARENT'
    SQL>

  • How to make before delete trigger

    Hi all
    I want make before delete trigger
    I have 2 tables hr_api_transactions and new_table
    when I delete records from hr_api_transations table
    then that deleted record should be stored/insert in new_table table
    for that purpose I need before delete trigger
    How can I make It?

    Hi
    I have written following code but it gives an error
    CREATE OR REPLACE TRIGGER before_delete_trigger
        BEFORE DELETE
            ON HR_API_TRANSACTIONS
            FOR EACH ROW
        DECLARE
        BEGIN
            delete from new_table where new_table.name = OLD.hr_api_transactions.api_addtnl_info;
        END;
    TRIGGER BEFORE_DELETE_TRIGGER compiled
    Errors: check compiler logafter show errors it shows
    4/54 PL/SQL: ORA-00904: "OLD"."HR_API_TRANSACTIONS"."API_ADDTNL_INFO": invalid identifier
    4/9 PL/SQL: SQL Statement ignoredhere hr_api_transaction is table which contain API_ADDTNL_INFO column
    and name column of new_table and API_ADDTNL_INFO column of
    HR_API_TRANSACTIONS table are same

  • Get current SQL instance name with PowerShell

    Hi all,
    I'm preparing SQL agent job that will backup all jobs on SQL server. Main step is PoswerShell script. I want that job to be universal for all servers. The first parameter that I need to send to script is instancename.
    I want to use variable as InctanceName parameter. So, when I run this job on particular server this variable must get current SQL instance name.
    I can use $env:computername for default instances but I cannot use it with named instances or with clustered instances. Some solutions like using 'HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL' keys won't work because of number of
    instanses can be running on one machine.
    How to get only current SQL instance name?

    Hi, 
    Thank you for your answers.
    I found this solution:
    $serverInstance = "$(ESCAPE_DQUOTE(SRVR))"
    Working perfect.

  • Before delete trigger?

    We are trying to determine who (like in what applicaton) is deleting rows in one table that leaves "orphaned" rows in another.
    We create the following trigger...
    create or replace Trigger EFA_TRG_AUDIT
    before delete on EFA_EXTERNAL_FILE_ATTACHMENT
    for each row
    declare
    OS_USER varchar2 (20);
    HOST varchar2 (20);
    MODULE varchar2 (48);
    SESSION_USER varchar2 (20);
    Begin
    if :old.EFA_LDS_UID is not null then
    SELECT substr(SYS_CONTEXT ('USERENV', 'SESSION_USER'),1,20) into SESSION_USER from dual;
         SELECT module into MODULE from v$session where audsid=userenv('SESSIONID');
         SELECT substr(SYS_CONTEXT ('USERENV', 'HOST'),1,20) into HOST from dual;
         SELECT substr(SYS_CONTEXT ('USERENV', 'OS_USER'),1,20) into OS_USER from dual;
    insert into EFAA_EFA_AUDIT values(
         :old.EFA_UID,
         :old.EFA_SYT_CODE_PARENT,
         :old.EFA_PARENT_KEY,
         :old.EFA_SEQUENCE,
         :old.EFA_FILENAME,
         :old.EFA_DESC,
         :old.EFA_LDS_UID,
         :old.EFA_CREATE_DATE,
         :old.EFA_USR_UID_CREATED_BY,
         :old.EFA_LAST_UPDATE_DATE,
         :old.EFA_USR_UID_UPDATED_BY,
         :old.EFA_FAT_CODE,
         :old.EFA_FILE_SIZE,
         'DELETE',
    HOST,
    OS_USER,
         MODULE,
    User,
         Sysdate);
    end if;
    end;
    This will create an "audit table" which works fine but includes ALL deletes including valid deletes that leave no "orphans" (EFA_LDS_UID).
    The LDS table can have rows that are not related to the EFA so a constraint cannot be used.
    Any ideas?

    no need to clean up the data. just create the FK as NOVALIDATE
    from the SQL Reference manual:
    ENABLE NOVALIDATE ensures that all new DML operations on the constrained data comply with the constraint. This clause does not ensure that existing data in the table complies with the constraint and therefore does not require a table lock

  • How to get the SQL which invoked a trigger

    Hi,
    I have a table from which the rows are getting deleted without our knowledge.
    To track this I've put a trigger on delete of this table. I want to know which SQL is actually invoking this Delete trigger so that I can capture it inside the trigger and log it somewhere so that I can analyze from where this SQL is fired.
    Please let me know if any one can help me regarding this.
    Thanks,
    Makrand

    If possible try and explore the FGA (Fine Grained Auditing) option . You may not need to create any triggers on the table and look up V$ views.
    Instead, define a RULE on the table. FGA will track the DML operation performed based on the RULE you defined
    i.e Consider a policy/Rule defined on the table TEMP as follows.
    begin
    dbms_fga.add_policy (
    object_schema => 'SCHEMA_NAME',
    object_name => 'TEMP',
    policy_name => 'TEMP_DELETE',
    audit_column => NULL,
    audit_condition => NULL,
    statement_types => 'DELETE'
    end;
    DBA_FGA_AUDIT_TRAIL view can then give you all the information required.
    You will need to have execute privilege on DBMS_FGA package.
    FGA will help if you are on 10g. In 9i it has a limitation – It can only use SELECT and not the other DML operations. So if you are on 9i, follow what the other members have mentioned ‘cause FGA will not be of much help to you.
    I[b] have not used this feature - Maybe you can give it a try and update the forum members. The limitation using FGA is that Auditing on the table is still enabled when ROLLBACK statement is issued.
    My preference will be using this feature instead of writing triggers on the table.
    Try using Google search and get more info on the FGA.. Good Luck !
    Shailender Mehta

  • Get current table ID before data insert

    Hi, Friends, anyone know, how coldfusion can get the current
    table ID before insert into database.
    The table ID is auto generated.
    thanks.

    hi,PatWeb, Sabaidee
    I tried the PreserveSingleQuotes, but not work, will try the
    HTMLEditFormat() .
    I had to store the compete code, for the horizontal layout of
    the video at once, that by following the attached code below.
    otherwise, it is vertical layout if I only store the .swf
    file name in the db.
    Any good idea?
    Coldfusion have muh advantage than other language when apply
    it video application, but so far, I didnot see.
    Thanks and Regards
    David
    <CF_Columns Cols="3" Records="#list.RecordCount#">
    <table border=0>
    <tr>
    <!--- Loop through the number of columns desired. --->
    <cfloop index="LoopCount" from="1" to="3">
    <!--- Access the start and end variables created by the
    custom tag. --->
    <cfset #start#=("start" & #LoopCount#)>
    <cfset #end#=("end" & #LoopCount#)>
    <td valign="top">
    <cfoutput query="list" startrow="#Evaluate(start)#"
    maxrows="#Evaluate(end)#">
    #State#<br>
    </cfoutput>
    </td>
    </cfloop>
    </tr>
    </table>

  • Passsing value to Before Delete Trigger

    I've never seen this done and wanted to see if it's even possible.
    They have created an application using access to fill out a form that a user is signed into. Once the form is created they submit the data to Oracle calling a process as a generic user. They want to be able to capture the user that was logged into Access to update when the trigger is fired and audit record created.
    I'm fairly new to what they are doing here and I think the easiest is just to create a procedure to update the audit table and delete the record, and forget about trying to use a trigger for this purpose.
    Any thoughts out there that might have more experience in this area.
    Thanks

    ...and when that package state is discarded by a patch release the sumbit button on the access form will stop working randomly, and the users will be figure out that they need to click the button twice sometimes and just to be safe always, and you'll end up with loads of duplicated audit entries.
    ...and when someone deletes by logging in as the "generic user" direct from an Access query, or ODBC or SQL*Plus or some random other tool, you'll have no idea who did it.
    The generic user idea is a bad one.

  • Help on delete trigger

    Hi all,
    I have a situation like this
    I have a table like
    SQL> desc system_user
    Name Null? Type
    ID NOT NULL NUMBER(12)
    USER_ID NOT NULL VARCHAR2(30)
    SQL> SELECT * FROM SYSTEM_USER
    2 ORDER BY CTUT_ID;
    CTUT_ID CURRENT_USER_ID
    1 KTYLOR
    2 EXAMPLE
    3 SCOTT
    SQL> DESC ALL_USERS;
    Name Null? Type
    USERNAME NOT NULL VARCHAR2(30)
    USER_ID NOT NULL NUMBER
    CREATED NOT NULL DATE
    What i need to do is i need to have before delete trigger to check the following condition when user try to delete a record in table
    SYSTEM_USER
    1) suppose user is trying to delete a record "SCOTT" IN TABLE
    SYSTEM_USER
    CONDITION SHOULD CHECK THAT IF USER_NAME EXITS IN TABLE "ALL_USER"
    1)IF HE EXITS THEN RAISE ERROR
    2)IF HE IS NOT EXITS THEN DELETE THE RECORD IN TABLE "SYSTEM_USER"
    SO I WROTE A CODE FOR TRIGGER
    SQL> CREATE OR REPLACE TRIGGER TIBD_USER
    2 BEFORE DELETE ON SYSTEM_USER FOR EACH ROW
    3 DECLARE
    4 FOUND_USER NUMBER(2);
    5 BEGIN
    6 SELECT COUNT(*) FROM ALL_USERS
    7 WHERE USERNAME = :OLD.USER_ID;
    8 IF FOUND_USER = 0 THEN
    9 DELETE FROM SYSTEM_USER
    10 WHERE ROWID := :NEW.ROWID;
    11 ELSE
    12 RAISE_APPLICATION_ERROR(-20000,'USER FOUND IN ALL_USERS TABLE');
    13 END IF;
    14 END TIBD_USER;
    15 /
    Warning: Trigger created with compilation errors.
    SQL> SHOW ERRORS
    Errors for TRIGGER TIBD_USER:
    LINE/COL ERROR
    7/1 PL/SQL: SQL Statement ignored
    8/13 PL/SQL: ORA-00920: invalid relational operator
    ANY HELP PLEASE

    1 CREATE OR REPLACE TRIGGER TIBD_USER
    2 BEFORE DELETE ON SYSTEM_USER FOR EACH ROW
    3 DECLARE
    4 FOUND_USER NUMBER(2);
    5 BEGIN
    6 SELECT COUNT(*) INTO FOUND_USER FROM ALL_USERS
    7 WHERE USERNAME = :OLD.USER_ID;
    8 IF FOUND_USER = 0 THEN
    9 DELETE FROM SYSTEM_USER
    10 WHERE ROWID = :OLD.ROWID;
    11 ELSE
    12 RAISE_APPLICATION_ERROR(-20000,'USER FOUND IN ALL_USERS TABLE');
    13 END IF;
    14* END TIBD_USER;
    SQL> /
    Trigger created.
    WHEN I DELETE A RECORD IT IS GIVING ME THAT
    SQL> DELETE FROM SYSTEM_USER
    2 WHERE CTUT_ID = 3;
    DELETE FROM SYSTEM_USER
    ERROR at line 1:
    ORA-04091: table SYSTEM_USER is mutating, trigger/function may not see it
    ORA-06512: at "TIBD_USER", line 7
    ORA-04088: error during execution of trigger 'TIBD_USER'

  • Help with a Before Delete Triggger

    Hello:
    When I do a delete operation on a table that has the following trigger, it comes up with an error message,
    ":ORA-04091: table INNOBOX.SUGGEST is mutating, trigger/function may not see it
    ORA-06512: at "INNOBOX.DELSUGGEST", line 44
    ORA-04088: error during execution of trigger 'INNOBOX.DELSUGGEST'"
    Can somebody tell me what I am doing wrong?
    CREATE OR REPLACE TRIGGER INNOBOX.delSuggest
    BEFORE DELETE
    ON INNOBOX.SUGGEST
         FOR EACH ROW
              BEGIN
                   INSERT INTO INNOBOX.SUGGEST_LOG
                        Sugg_Log_ID_N,
                        Sugg_No_N,
                        Cat_CD_C,
                        Liaison_CD_C,
                        S_Desc_C,
                        L_Desc_C,
                        S_Stat_CD_C,
                        S_Stat_DT,
                        Benefit_C,
                        Cost_Sav_C,
                        Resol_C,
                        D_Stat_CD_C,
                        D_Stat_DT,
                        ACD_CD_C,
                             Cr_By_ID_C,
                        Cr_DT,
                        Up_By_ID_C,
                        Up_DT     
                   VALUES
                             INNOBOX.Suggest_Log_Seq.NEXTVAL,
                        :old.Sugg_No_N,
                        :old.Cat_CD_C,
                        :old.Liaison_CD_C,
                        :old.S_Desc_C,
                        :old.L_Desc_C,
                        :old.S_Stat_CD_C,
                        :old.S_Stat_DT,
                        :old.Benefit_C,
                        :old.Cost_Sav_C,
                        :old.Resol_C,
                        :old.D_Stat_CD_C,
                             :old.D_Stat_DT,
                             'D',
                             :old.Cr_By_ID_C,
                             :old.Cr_DT,
                             :old.Up_By_ID_C,
                             :old.Up_DT
                   DELETE SUGGEST WHERE Sugg_No_N = :old.Sugg_No_N
              END;
    Thanks.
    Venki

    Hi,
    Try to remove the last line from your trigger :
    DELETE SUGGEST WHERE Sugg_No_N = :old.Sugg_No_N, you delete a line from a table for which there is the same before delete trigger, also there is a muttating trigger.
    HTH,
    Nicolas.

  • Delete Trigger

    Hi,
    I got a question using triggers. I have a statement level delete trigger that calls a package function used to insert data into various archiving tables. In order to keep track of the deleted rows I have a row level delete trigger that keeps the deleted Ids of my objects in a special table that I later query in my statement level trigger.
    My main problem is that while all triggers are called properly and data is removed from desired tables, the data that should be inserted into my archiving tables does not appear until the trigger is fired again it appears. I don't really see what could cause data to be deleted and effectively removed while the data i want to insert does not appear until the next time the trigger is fired.
    could it be that i need to explicitely commit the inserted data ?
    If it's not clear, I could always post some of the code used.
    Thanks,
    Greg

    Sure (I hope it won't be too messy though).
    ---- PACKAGE DEF.
    I have a package variable defined as follows:
    TYPE idTable IS TABLE OF NUMBER(19) INDEX BY BINARY_INTEGER;
    And my variables:
    del_oldRows idTable;
    del_emptyRows idTable;
    ---- PACKAGE BODY
    In the body I have calls like this:
    PROCEDURE delete_transaction(aID NUMBER) IS
    BEGIN
    -- I) Add New Data into appropriate archiving tables
    -- 1) Many-to-Many Table for first object
    INSERT ALL INTO X_OBJ1_OBJ2_DLTD
    DLTD_ID,
    OBJ1_ID,
    OBJ2_ID
    SELECT
    ID,
    OBJ1_ID,
    OBJ2_ID
    FROM X_OBJ1_OBJ2
    WHERE (X_OBJ1_OBJ2.ID = aID )
    -- 2) Second object <SNIP>
    -- 1) Many-to-Many Table for first object
    DELETE FROM X_OBJ1_OBJ2
    WHERE (X_OBJ1_OBJ2.ID = aID );
    END delete_transaction;
    ---- Before Delete Trigger (Statement Level)
    This one resets the package in a consistent state:
    BEGIN
    mypackage.del_oldRows := mypackage.del_gatetrans_emptyRows;
    END;
    ---- After Delete Trigger (Row Level)
    This one adds Ids in my package variable:
    BEGIN
    mypackage.del_oldRows(mypackage.del_oldRows.COUNT + 1) := :OLD.ID;
    END;
    ---- After Delete Trigger (Statement)
    This one goes through each row in my package "table" and calls the function to add the related data in my archiving table:
    BEGIN
    FOR i IN 1 .. mypackage.del_oldRows.COUNT LOOP
    mypackage.delete_transaction(mypackage.del_oldRows(i));
    END LOOP;
    mypackage.del_oldRows := mypackage.del_emptyRows;
    END;
    ---- END
    Anyways that's the basic logic. Kinda what is suggested for mutating tables when playing with UPDATE triggers I guess. Here it's just because I want my triggers to be simple and focus on inserting the archiving data for the object triggering the... trigger while related objects that need to be archived should be taken care of in my package function. My problem is that the data is removed properly but not appears as inserted until the next time the trigger is fired, as if i was always "one" trigger late :(.
    If it's not clear enough, please let me know.
    Thanks,
    Greg

  • Delete trigger not working on delete button

    I have a form (parent) / report (children) combo page with all the default buttons (create, apply changes, delete, cancel) created from the wizard. I've created a before delete trigger on the parent table that basically finds all the children and deletes them. For debugging purposes, I've added some inserts into a test table to make sure my bind variables binding correctly (they are). When I confirm the java script delete and say ok, the insertion of the text for debugging purposes works fine, but the actual deletion of the other records does not. Any ideas why?

    Then it is easy-your delete process is not fireing!!
    Why...there may be many reasons....but I'm pretty sure that process is never fired!
    Look in your page or show us a demo on workspace

  • How can I get my trigger to see the SQL that activated the trigger?

    The catch here is that this is a standard edition instance so FGA is not available.
    TIA, Allen

    I would be very interested in why you would want the literal SQL...
    While this won't be particularly efficient, you can get the SQL currently being executed in a session via something like
    select sql_fulltext
       from v$sqlarea area,
            v$session sess
      where sess.sql_address = area.address
        and sess.sql_hash_value = area.hash_value
        and SYS_CONTEXT( 'USERENV', 'SID') = sess.sidI haven't tested that this returns the query that actually fired the trigger in every situation, but it's probably a reasonable guess...
    Justin

  • Newbie Trigger question - before delete

    We have a table A - Primary Key A1, and Table B has a column B1 foreign key to A1 column.
    We need to mass delete table A records which are more than 3 months old, but we do not want to delete Records from Table B, just nullify the foreign key column in table B.
    So "ON DELETE CASCADE" is not applicable in our situation. Is creating a trigger with before delete option the only way to solve the above?
    If yes, when inside the trigger action, how can I access the table A primary key value to find out if I have a possible match in table B? How to represent (current rows's A1 value) ?
    For example - trigger action
    CREATE TRIGGER DEL_A
    BEFORE DELETE ON A
    FOR EACH ROW
    DECLARE X;
    BEGIN
        SELECT COUNT(*) INTO X
        FROM B WHERE B1 = (current row's A1 value);
        IF X > 0
        THEN
           UPDATE B SET B1 = NULL
           WHERE B WHERE B1 = (current row's A1 value);
       END IF;
    ENDIs the above code correct, or is there any better way to do the same?
    Thanks in advance,
    Rumpa

    where B1 = :A1
    You probably mean "where b1 = :old.a1" ...
    Regards,
    Rob.

  • How to get a SQL statement that trigerred a trigger ?

    I'd like to trace all insert and update operations done on a table.
    So, how can I get the SQL statement that triggered a trigger ?
    Thanks

    Use AUDIT to trace all sql statement about table, views etc. (except column) :
    http://download-west.oracle.com/docs/cd/B14117_01/server.101/b10759/statements_4007.htm#SQLRF01107
    Or, if you are in 9i or later, you can use DBMS_FGA (you can audit just a column) :
    http://download-west.oracle.com/docs/cd/B14117_01/appdev.101/b10802/d_fga.htm#ARPLS015
    Nicolas.

Maybe you are looking for