AFTER SERVERERROR trigger exceptions

AFTER SERVERERROR triggers fire after an Oracle error is raised, unless the error is one of the following:
ORA-00600 Oracle internal error (understandable)
ORA-01034 Oracle not available (understandable)
ORA-01403 No data found
ORA-01422 Exact fetch returns more than requested number of rows (too many rows)
ORA-01423 Error encountered while checking for extra rows in an exact fetch
ORA-04030 Out-of-process memory when trying to allocate N bytes
Anyone know why these errors are excluded?
Gus

My guess would be that 1403 and 1422 are not really errors, but exception conditions that may or may nor be expected. Any select that returns no rows raise 1403, and it is up to the client to determine whether or not that is an error. I would assume similar reasoning for 1422.
For the 4030 error, I would assume that if there is no process memory, then the trigger could not fire because it would require more process memory to fire the trigger.
The oerr utility reports this for 1423:
01423, 00000, "error encountered while checking for extra rows in exact fetch"
// *Cause:
// *Action: See the following error and take appropriate action.I would strongly suspect that the following error would likely be one of 600, 1034, 3113, or one of the similar something bad happend but I don't know what errors.
HTH
John

Similar Messages

  • Is there an AUDIT option like AFTER SERVERERROR database trigger?

    I want to log any and every error-exception in a test database for a period.
    I have seen DBMS_UTILITY.FORMAT_ERROR_BACKTRACE article published on Oracle Magazine;
    http://www.oracle.com/technology/oramag/oracle/05-mar/o25plsql.html
    But before trying to build a custom application like this one;
    http://apex.oracle.com/pls/otn/f?p=2853:4:1160653345033883::NO::P4_QA_ID:5922
    1- I wanted to be sure if there is a specific WHENEVER NOT SUCCESSFUL Audit option for this need?
    2- Also is there a way to capture NO_DATA_FOUND exception with AFTER SERVERERROR database trigger?
    Thank you,
    Best regards.

    some stuff like following;
    1)
    -- the right one is conn hr/hr
    conn hr/eychar
    2)
    -- the right one is grant select on employees to public;
    grant select onnnn employees to public;
    3)
    create or replace procedure p1 as
    begin
    raise_Application_error(-20001, 'catch me if you can');
    end;
    exec p1;
    again thank you for your interest Michaels.

  • Hide an error from the application using a servererror trigger?

    We have an application designed for an old oracle version which issues some sql which is no more supported in todays database version.
    We want to use the application unchanged with a new database server.
    Old Server Version: 7.3.4 (still in production...)
    New Server Version: 10.2 or 11.2
    The application issues an
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS ;
    which results in ORA-01986 and the application dies.
    We would like to hide the error 01986 from the application using a trigger:
    create or replace
    trigger catch01986
      after servererror
      on schema
      begin
        if (ora_is_servererror (1986)) then
          null; -- what to do here? we want clear the ora-01986 from the error stack
        end if;
      end catch01986;How to handle the error, so that the alter session set ... statement is just ignored and no error code is returned to the application?
    I asked already some days ago in Database-General Forum, but triggers belong to PL/SQL, so i repost here.
    Tnx for help in advance!

    Hi,
    hoek wrote:
    A totally weird and untested (and unable to test today) thought:
    http://technology.amis.nl/blog/447/how-to-drive-your-colleagues-nuts-dbms_advanced_rewrite-oracle-10g
    Very interesting for real dirty solution.
    Does not work for my problem, DBMS_ADVANCED_REWRITE works only for select statements.
    BEGIN
       SYS.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE (
       'alter_session_equivalence',
       'ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS',
       'ALTER SESSION SET OPTIMIZER_MODE = RULE',
       FALSE);
    END;
    ORA-30389: the source statement is not compatible with the destination statement
    ORA-00903: invalid table name
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 29
    ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 185
    ORA-06512: at line 2
    30389. 00000 -  "the source statement is not compatible with the destination statement"
    *Cause:    The SELECT clause of the source statement is not compatible with
               the SELECT clause of the destination statement
    *Action:   Verify both SELECT clauses are compatible with each other such as
               numbers of SELECT list items are the same and the datatype for
               each SELECT list item is compatible
    hoek wrote:You already had some trigger code, catching the error and sending it to null, why didn't that work?The trigger is fired when the error occurs, but after completion of the trigger, the error code is still delivered to the client.
    I dont know how to handle the error within the trigger.
    Does the client read the error stack and does it die after reading an error from the stack?The client just checks the error code. On error it terminates.
    With the SERVERERROR TRIGGER i did the following tests:
    Test 1: trigger does nothing
    CREATE OR REPLACE
    TRIGGER CATCH01986
      AFTER SERVERERROR
      ON SCHEMA
      BEGIN
        IF (ORA_IS_SERVERERROR (1986)) THEN
          NULL;
        END IF;
      END CATCH01986;
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
    ORA-01986: OPTIMIZER_GOAL is obsolete
    01986. 00000 -  "OPTIMIZER_GOAL is obsolete"
    *Cause:    An obsolete parameter, OPTIMIZER_GOAL, was referenced.
    *Action:   Use the OPTIMIZER_MODE parameter.
    -- Client Application reports errorcode 1986Test 2: Trigger raises NO_DATA_FOUND
    CREATE OR REPLACE
    TRIGGER CATCH01986
      AFTER SERVERERROR
      ON SCHEMA
      BEGIN
        IF (ORA_IS_SERVERERROR (1986)) THEN
          RAISE NO_DATA_FOUND;
        END IF;
      END CATCH01986;
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
    ORA-04088: error during execution of trigger 'AH.CATCH01986'
    ORA-01403: no data found
    ORA-06512: at line 9
    ORA-01986: OPTIMIZER_GOAL is obsolete
    04088. 00000 -  "error during execution of trigger '%s.%s'"
    *Cause:    A runtime error occurred during execution of a trigger.
    *Action:   Check the triggers which were involved in the operation.
    -- Client Application reports errorcode 4088Test 3: Trigger raising an APPLICATION ERROR
    CREATE OR REPLACE
    TRIGGER CATCH01986
      AFTER SERVERERROR
      ON SCHEMA
      BEGIN
        IF (ORA_IS_SERVERERROR (1986)) THEN
            DBMS_STANDARD.RAISE_APPLICATION_ERROR(-20999, 'this makes no sense', true);
        END IF;
      END CATCH01986;
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
    ORA-00604: error occurred at recursive SQL level 1
    ORA-20999: this makes no sense
    ORA-06512: at line 10
    ORA-01986: OPTIMIZER_GOAL is obsolete
    00604. 00000 -  "error occurred at recursive SQL level %s"
    *Cause:    An error occurred while processing a recursive SQL statement
               (a statement applying to internal dictionary tables).
    *Action:   If the situation described in the next error on the stack
               can be corrected, do so; otherwise contact Oracle Support.
    -- Client Application reports errorcode 604Test 4: Adding an EXCEPTION part to the trigger does not help, this will catch only exceptions raised while the trigger executes:
    CREATE OR REPLACE
    TRIGGER CATCH01986
      AFTER SERVERERROR
      ON SCHEMA
      BEGIN
        IF (ORA_IS_SERVERERROR (1986)) THEN
            DBMS_STANDARD.RAISE_APPLICATION_ERROR(-20999, 'this makes no sense', true);
        END IF;
      EXCEPTION
        WHEN OTHERS THEN
          NULL;
      END CATCH01986;
    ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
    ORA-01986: OPTIMIZER_GOAL is obsolete
    01986. 00000 -  "OPTIMIZER_GOAL is obsolete"
    *Cause:    An obsolete parameter, OPTIMIZER_GOAL, was referenced.
    *Action:   Use the OPTIMIZER_MODE parameter.
    -- Client Application reports errorcode 1986So i do not know what to do inside the trigger to clean the error stack so that the client will receive no errorcode.

  • SERVERERROR trigger

    One of the things I have come up against a lot in triggers is resetting state if an error occurs. For example, to get around the mutating table issue, I find quite often I do stuff like this :
    [Before {event} statement trigger]
    Initialisation
    [Before {event} for each row trigger]
    Add current row ID to PL/SQL table
    [After {event} statement trigger]
    Iterate over array and process (free from mutating table restrictions)
    We have an instance SERVERERROR trigger that logs database errors and contextual information in a table. This works really well and is very useful for diagnosing problems - particularly because we have multiple applications sharing the same DB instance and it allows us to centralise the error handling (at least as far as this goes).
    It occurred to me that it would be nice to allow a trigger to register an on-error cleanup handler. This would simplify the trigger error handling logic considerably because you wouldn't need multiple EXCEPTION handlers. One of the problems with defining EXCEPTION handlers at a high level is that you lose the context of the error (i.e. where the error actually occurred). So, I was hoping to do something like this :
    [Before {event} statement trigger]
    Register cleanup function
    Initialisation
    [Before {event} for each row trigger]
    Add current row ID to PL/SQL table
    [After {event} statement trigger]
    Iterate over array and process (free from mutating table restrictions)
    Deregister cleanup function
    and then in the SERVERERROR trigger ...
    if cleanup function registered
    execute cleanup function (using execute immediate)
    end if;
    The problem is that the SERVERERROR trigger seems to execute using DEFINER rights, so it doesn't see the cleanup function, which exists in the callers schema. Is there any way to have a SERVERERROR trigger execute with AUTHID CURRENT_USER, or alternatively another way to achieve my goal?
    Thanks for any suggestions.

    You can try oracle's builtin auditing feature to take care of this particular requirement. It's a simple three step process.
    1- Set audit_trail = true in parameter file
    2- Run this command while connected to a privileged user
        audit session whenever not successful;
    3- Query data dictionary view to see failed logins
    SQL> SELECT os_username,
      2     username,
      3     terminal,
      4     returncode
      5  FROM dba_audit_trail
      6  /
    OS_USERNAME                    USERNAME        TERMINAL        RETURNCODE
    DATABASE_IT\Administrator      ANWAR           DATABASE_IT           1017-------
    Anwar

  • Use of "DBA_OBJECTS" in "AFTER CREATE" Trigger

    Hi,
    We would like to store some extra information about our objects we have in the database. To do so we tought of the idea of creating a 'documenting' table containing an object_id that references to the object_id from the view dba_views.
    Now we want to automatically create a new record in our documenting table when a new object is created, in the first stage this should only contain the object_id
    To accomplish this we are using an 'AFTER CREATE' trigger, but when this trigger fires and the code searches for the new object_id in dba_objects, it does not return any records and generates an error. Likely because when the trigger is executed, the view is not yet updated?
    create or replace
    TRIGGER TRG_TEST
    AFTER CREATE ON SCOTT.SCHEMA
    DECLARE
    tmp VARCHAR2(50);
    BEGIN
    dbms_output.put_line(ora_dict_obj_name);
    select object_id
    into tmp
    from dba_objects
    where object_name = ora_dict_obj_name;
    dbms_output.put_line(tmp);
    END;
    Error report:
    ORA-04088: Fout bij uitvoering van trigger 'SCOTT.TRG_TEST'.
    ORA-01403: Geen gegevens gevonden.
    ORA-06512: in regel 6
    04088. 00000 - "error during execution of trigger '%s.%s'"
    *Cause:    A runtime error occurred during execution of a trigger.
    *Action:   Check the triggers which were involved in the operation.
    It's in dutch, so I'll have a go at translating:
    Error report:
    ORA-04088: Exception while executing trigger 'SCOTT.TRG_TEST'.
    ORA-01403: No data found
    ORA-06512: in rule 6
    04088. 00000 - "error during execution of trigger '%s.%s'"
    *Cause:    A runtime error occurred during execution of a trigger.
    *Action:   Check the triggers which were involved in the operation.
    Does anyone have an idea of how I can accomplish what I'm trying to do here.. Or maybe something I'm doing wrong?
    Thanks in advance!
    Davy

    What is "ora_dict_obj_name" defined as?
    Another option might be to setup a DBMS_SCHEDULER job to run the following insert
    firstly though, create the following table ;
    create document_table as (select * from dba_objects where rownum < 1)and then setup a DBMS_SCHEDULER job to run the following:
    begin
      insert into document_table
      (select dbo.*
       from   dba_objects    dbo
             ,document_Table dtb
       where  dbo.Object_ID = dtb.Object_ID(+)
       and    dtb.Object_ID is null);
       commit;
       exception
        when others then
          rollback;
          -- log a message somewhere with the error, i.e. SQLERRM
    end;
    /Note, I specified all columns, but you'll probably specify explicitly which column you require, in which case the CREATE table would change as well.
    Then you won't have a need for any trigger, and can better manage when you want your documentation to be updated.
    Another option might be to use COMMENT, which can be used on tables, views, materialized views, but won't cover all objects
    to the extent you might want.
    SQL> desc emp2
    Name                                                                                                  
    EMPNO                                                                                                 
    JOB                                                                                                   
    START_DATE                                                                                            
    SAL                                                                                                   
    DEPT                                                                                                  
    END_DATE                                                                                              
    SQL> comment on column emp2.sal is 'Existing Salary of employee as paid at most recent month end';

  • Error in After Report Trigger

    Hi,
    I've developed a report in HRMS for my client which collated the Vacation Accrual data of all employees. When i run the report for all employees which is an optional parameter it throwing the below error.
    REP-0300: ORACLE error occurred.
    REP-0069: Internal error
    In-process job terminated:Terminated with error:
    REP-300:
    During debugging i found that in the After Report Trigger , after the return statement, the below error is being thrown. I couldn't identify the exact source of the error. Any help on this would be much appreciated. Below is the After Report Trigger code.
    function AfterReport return boolean is
    begin
    srw.MESSAGE (12345, 'After Report - Before Return');
    return (TRUE);
    srw.MESSAGE (12345, 'After Report - After Return');
    end;
    Thanks
    Elango

    After spending a lot of time in analyzing, i ripped apart each and every part of the report and found a function where am doing a varchar to date conversion. Then i ran the query individually and picked up the below error.
    ORA-01841: (full) year must be between -4713 and +9999, and not be 0
    Then i identified the record which has incorrect data and modified it thru applications. Oracle Internal error basically arises due to datatype mismatch and its always better to use exception blocks with log messages wherever its applicable.
    Thanks
    Elango.

  • :NEW cannot be used in After Delete Trigger ?

    Hi,
    Is there any way to get the :NW.value in the After delete trigger for each row. My requirement is audit log of the end user DML operations along with user Name (HERE THE USER IS NOT THE ORACLE USER, BECAUSE OF THE LARGE NUMBER OF END USERS WE ARE MAINTAINING ONE TABLE TO CREATE USER NAME & PASSWORD, WHEN THE USER LOGIN TO ORACLE FORM SCREEN, ASSIGN THE USER NAME TO GLOBAL VARIABLE) & Action Date.
    Here is my code for trigger - It is working fine with INSER & UPDATE but for DELETE User is NULL
    CREATE OR REPLACE TRIGGER Tgr_stud_det
    AFTER INSERT OR UPDATE OR DELETE ON student_details
    FOR EACH ROW
    DECLARE
    BEGIN
    IF Inserting THEN
    -------------INSERT VALUE---------------
    INSERT INTO Log_student_details
    (Seq,
    App_User,
    Action,
    Action_Date,
    stud_name,
    stud_age,
    stud_sex)
    VALUES
    (stud_sequence.NEXTVAL,
    :NEW.App_User,
    'INSERT',
    SYSDATE,
    :NEW.stud_name,
    :NEW.stud_age,
    :NEW.stud_sex);
    -------------DELETE VALUE---------------
    ELSIF Deleting THEN
    INSERT INTO Log_student_details
    (Seq,
    App_User,
    Action,
    Action_Date,
    Comment_Up,
    stud_name,
    stud_age,
    stud_sex)
    VALUES
    (stud_sequence.NEXTVAL,
    :OLD.App_User,
    'DELETE',
    SYSDATE,
    NULL,
    :OLD.stud_name,
    :OLD.stud_age,
    :OLD.stud_sex);
    ELSIF Updating THEN
    -------------UPDATE VALUE---------------
    INSERT INTO Log_student_details
    (Seq,
    App_User,
    Action,
    Action_Date,
    Comment_Up,
    stud_name,
    stud_age,
    stud_sex)
    VALUES
    (stud_sequence.NEXTVAL,
    :NEW.App_User,
    'UPDATE',
    SYSDATE,
    'NEW VALUE',
    :NEW.stud_name,
    :NEW.stud_age,
    :NEW.stud_sex);
    INSERT INTO Log_student_details
    (Seq,
    App_User,
    Action,
    Action_Date,
    Comment_Up,
    stud_name,
    stud_age,
    stud_sex)
    VALUES
    (stud_sequence.CURRVAL,
    :NEW.App_User,
    'UPDATE',
    SYSDATE,
    'OLD VALUE',
    :OLD.stud_name,
    :OLD.stud_age,
    :OLD.stud_sex);
    END IF;
    EXCEPTION
    WHEN OTHERS THEN
    NULL;
    END Tgr_stud_det;
    Thanks in advance.

    Rizly,
    As i mentioned in the above post, you should remove the references of :old and :new when you are trying to use the global variables. These values are only significant when you the talk about the record in the table.
    For the scenario, you explained, your trigger would insert two records....The trigger would be fired twice.. once during the insert and once during the delete. The audit table will have two records indicating both the actions..
    Take a look at this example below...I am artificially manufacturing a user id in the package test_pkg and using that in the insert trigger. As i explained above, you dont need the :old and :new references because the user id is not a column in the table . hence the :old and :new references have no relevance.
    Also note that, for the delete, I use the :old value and for the insert, I use the :new value.
    for update, I assume you want to store the old record and hence used :old (you can of course use :new too..technically.).
    I don't have access to a forms environement, but the user id logic should be similar to what I described below.
    sql> create table t(
      2     id number,
      3     name varchar2(20)
      4  );
    Table created.
    sql> create table t_audit
      2     ( id number,
      3       name varchar2(20),
      4       action varchar2(20),
      5       user_id varchar2(20)
      6  );
    Table created.
    sql> create or replace package test_pkg as
      2      function get_user_id return varchar2;
      3  end test_pkg;
      4  /
    Package created.
    sql> create or replace package body test_pkg as
      2      function get_user_id return varchar2 is
      3      begin
      4          return 'USER' || to_char(sysdate,'HH24:MI');
      5      end get_user_id;
      6  end test_pkg;
      7  /
    Package body created.
      1  create or replace trigger trg_biud_t
      2     before insert or update or delete on t
      3     for each row
      4  begin
      5     if INSERTING then
      6        insert into t_audit values (:new.id, :new.name, 'INSERT',test_pkg.get_user_i
      7     elsif UPDATING then
      8        insert into t_audit values (:old.id, :old.name, 'UPDATE',test_pkg.get_user_i
      9     elsif DELETING then
    10        insert into t_audit values (:old.id, :old.name, 'DELETE',test_pkg.get_user_i
    11     end if;
    12* end;
    sql> /
    Trigger created.
    sql> select * from t;
    no rows selected
    sql> select * from t_audit;
    no rows selected
    sql> insert into t values (100, 'Rajesh');
    1 row created.
    sql> insert into t values (200,'Kumar');
    1 row created.
    sql> delete from t where id = 200;
    1 row deleted.
    sql> commit;
    Commit complete.
    sql> select * from t
      2  /
            ID NAME
           100 Rajesh
    sql> select * from t_audit;
            ID NAME                 ACTION               USER_ID
           100 Rajesh               INSERT               USER15:36
           200 Kumar                INSERT               USER15:36
           200 Kumar                DELETE               USER15:37

  • Facing issue in after report trigger in XML publisher

    HI All,
    I have a XML template in that i am calling a after report trigger like below :
    <dataTrigger name="afterReport" source="apps.testpkg.testupdate_fun(:HEADER_ID)"/>
    I am passing the header_id from my header block to the function.
    My Function looks like below:
    FUNCTION testupdate_fun(P_HEADER_ID IN NUMBER ) RETURN BOOLEAN AS
    BEGIN
    UPDATE TEST_TABLE SET PROCESS_FLAG='P' WHERE HEADER_ID=P_HEADER_ID;
    COMMIT;
    return true;
    EXCEPTION
    WHEN OTHERS THEN
    return false;
    END;
    The problem i am facing is it is updating only one record in the table.but in my header data block i am getting the details for more order numbers with header id like 1,2,3..., but it is updating only one header id in table, please help me out how to update record for all the header_id.
    Thanks

    Examples of combining all IDs into comma-separate list can be found here: http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php . That list you need to send as parameter to the trigger. In the trigger you may split it again and update the records one-by-one, or you can build an EXECUTE IMMEDIATE statement to update the table, and in that statement the list can be used as a whole, no need to split it. Please, advise on which steps of this process you need more detailed assistance.

  • After Update Trigger executes twice when single row is uptd thro proc

    We have the below trigger in our db. When a single record is updated using a procedure the trigger is executed twice and it inserts two records in other table.
    But when i issue an update statement using any sql client tool it is executing only once and inserts only one record in other table.
    Can any one please help me to find the reason?
    Trigger:*
    create or replace TRIGGER CX_HEADER_ESCL_T1 AFTER UPDATE OF STATUS ON CX_HEADER
    FOR EACH ROW
    DECLARE
    "b1-CTRIYJ" boolean := FALSE;
    BEGIN
    IF UPDATING('STATUS') AND(:NEW.status = 'SUCCESS') THEN
    "b1-CTRIYJ" := TRUE;
    END IF;
    IF "b1-CTRIYJ" = TRUE THEN
    INSERT
    INTO siebel.s_escl_req(req_id, created, bt_row_id, rule_id, tbl_name, created_by, group_id)
    VALUES('11111111', CURRENT_DATE, :NEW.row_id, '1-CTRIYJ', 'CX_HEADER', :NEW.last_upd_by, '1-2CU3');
    "b1-CTRIYJ" := FALSE;
    END IF;
    END;
    Procedure:
    CREATE OR REPLACE
    PROCEDURE CLOSE_BATCH
    (ChildRecordCount IN NUMBER, HeaderId IN VARCHAR2, CompletionStatus OUT VARCHAR2) AS
    CafeChildCount NUMBER;
    BEGIN
    select count(*) into CafeChildCount from SIEBEL.CX_CHILD where HEADER_ID=HeaderId;
    IF ChildRecordCount = CafeChildCount THEN
    update SIEBEL.CX_HEADER set STATUS ='SUCCESS', MODIFICATION_NUM = MODIFICATION_NUM+1 where HEADER_ID=HeaderId;
    CompletionStatus := 'SUCCESS';
    ELSE
    update SIEBEL.CX_CHILD set STATUS='FAILED' where HEADER_ID=HeaderId;
    update SIEBEL.CX_HEADER set STATUS='FAILED' where HEADER_ID=HeaderId;
    CompletionStatus := 'FAILED';
    END IF;
    commit;
    /*CompletionStatus := 'SUCCESS';*/
    EXCEPTION
    WHEN OTHERS THEN
    CompletionStatus := SQLCODE;
    rollback;
    END;

    Your problem seems not be related to the trigger restart issue I have already mentioned because you are using a AFTER UPDATE trigger and not a BEFORE UPDATE trigger:
    >
    BEFORE Triggers Fired Multiple Times
    If an UPDATE or DELETE statement detects a conflict with a concurrent UPDATE, then Oracle Database performs a transparent ROLLBACK to SAVEPOINT and restarts the update. This can occur many times before the statement completes successfully. Each time the statement is restarted, the BEFORE statement trigger is fired again. The rollback to savepoint does not undo changes to any package variables referenced in the trigger. Your package should include a counter variable to detect this situation.
    >
    If you are sure that you update a single row and that your trigger fires twice and if you can easiily reproduce the issue, I recommend that you contact Oracle Support and create a Service Request for your issue that could be an Oracle bug.

  • Closing DBA session in AFTER LOGON trigger

    Hello *,
    this is my first question here and my first piece of code in oracle so please don't laugh ;-)
    I'm trying to create an AFTER LOGON trigger which disconnects a user if he/she tries to log in from an incorrect host.
    What should happen?
    User tries to connect.
    If he/she is permitted, a record is added to a table.
    If not, a record is added to another table and the user is disconnected using RAISE_APPLICATION_ERROR().
    After a number of issues I've got it working, except ... I have the feeling that RAISE_APPLICATION_ERROR() doesn't effect users with DBA privileges.
    Finally, I'm testing it with one ordinary user - DEF.
    The main idea is to disallow connections from user ABC which has DBA privileges.
    Tests using DEF are successful but when ABC tries to log in from an incorrect host, a record is added in pcbaudit_failed_logins but the user is not disconnected.
    The database is 9.2.0.8.0 and I'm prepared to post RDA report if it is required.
    Thank you for your help in advance - I hope I was kind enough :P
    Here's the code for the trigger:
    DROP TABLE pcbaudit_users;
    CREATE TABLE pcbaudit_users (username VARCHAR2(32) NOT NULL, host VARCHAR2(64) NOT NULL);
    CREATE INDEX idx_pcbaudit_users_username ON pcbaudit_users(username);
    CREATE INDEX idx_pcbaudit_users_host ON pcbaudit_users(host);
    DROP TABLE pcbaudit_logins;
    CREATE TABLE pcbaudit_logins (username VARCHAR2(32), ip_address VARCHAR2(15), host VARCHAR2(64), ts DATE);
    DROP TABLE pcbaudit_failed_logins;
    CREATE TABLE pcbaudit_failed_logins (username VARCHAR2(32), ip_address VARCHAR2(15), host VARCHAR2(64), ts DATE);
    CREATE OR REPLACE PUBLIC SYNONYM pcbaudit_users FOR sys.pcbaudit_users;
    CREATE OR REPLACE PUBLIC SYNONYM pcbaudit_logins FOR sys.pcbaudit_logins;
    CREATE OR REPLACE PUBLIC SYNONYM pcbaudit_failed_logins FOR sys.pcbaudit_failed_logins;
    GRANT SELECT ON sys.pcbaudit_users TO public;
    GRANT INSERT ON sys.pcbaudit_logins TO public;
    GRANT INSERT ON sys.pcbaudit_failed_logins TO public;
    INSERT INTO pcbaudit_users VALUES ('SYS', '%');
    INSERT INTO pcbaudit_users VALUES ('SYSTEM', '%');
    INSERT INTO pcbaudit_users VALUES ('ABC', '%');
    INSERT INTO pcbaudit_users VALUES ('DEF', '%');
    COMMIT;
    CREATE OR REPLACE
    TRIGGER logon_pcbaudit_trigger AFTER LOGON ON DATABASE
    DECLARE
         v_username     VARCHAR2(32); /* variable that will hold current username */
         v_host          VARCHAR2(4000); /* variable that will hold current host */
         v_allowed     NUMBER(1) := 0;
         PRAGMA          AUTONOMOUS_TRANSACTION;
    BEGIN
         SELECT     UPPER(USER), /* current user */
              UPPER(SYS_CONTEXT('USERENV', 'HOST')) /* current user host */
         INTO     v_username,
              v_host
         FROM     dual;
         /* debug */
    --     DBMS_OUTPUT.PUT_LINE(v_username || '@' || v_host);
         SELECT     1
         INTO     v_allowed
         FROM     pcbaudit_users
         WHERE     UPPER(username) = v_username
    AND (
                   UPPER(REPLACE(v_host, CHR(0), '')) LIKE UPPER(host) ESCAPE '!' /* fuck that shit! Something appends CHR(0) to its host... */
                   OR
                   v_host IS NULL /* fuck that shit! Some hosts are NULLs! */
    /* write log (user has logged in!) */
    INSERT
    INTO pcbaudit_logins
    (username, ip_address, host, ts)
    VALUES
    (v_username, SYS_CONTEXT('USERENV', 'IP_ADDRESS'), v_host, SYSDATE);
    COMMIT;
    EXCEPTION
         WHEN     NO_DATA_FOUND     THEN /* occurs when no matches were found; i.e. current username is not permitted to login from the current host */
              /* log the failed attempt */
              INSERT
              INTO     pcbaudit_failed_logins
              (username, ip_address, host, ts)
              VALUES
              (v_username, SYS_CONTEXT('USERENV', 'IP_ADDRESS'), v_host, SYSDATE);
    COMMIT;
              /* disconnect user */
              RAISE_APPLICATION_ERROR(-20001, v_username || '@' || v_host || ' is not allowed to connect.');
         WHEN     OTHERS THEN
              NULL; /* in this case, NULL is better than an error - if an error occurs, user will not be able to login. */
    END;

    Thank you for your reply!
    The situation is quite complicated.
    I am aware that a user with DBA privileges can drop the trigger, modify it, etc.
    There's an application on top of it and (i don't know why) it requires dba privileges. The point is, there are developers with access to the production database and my task is to stop them from logging in with this username.
    Since I'm creating a trigger, I've obviously have no other choice. I can't change the user's password because of number of reasons, I can't deny developers' IP addresses using sqlnet.ora because they need read-only access and so on.
    I realize that this is not the way that things are being done (development cycle), but I have no other choice.
    So, is there any other way?

  • After update trigger with condition

    Dear members,
    I have a table with multiple columns on each update on these columns I have to update another table columns.
    for one column the following trigger is working fine, but there are about more than 10 columns which I have to check for.
    I want to create only one after update trigger on this table and check which column is updated and update the same column in 2nd table.
    here is the trigger:
    CREATE OR REPLACE TRIGGER ABC_RATE_UPD
    AFTER UPDATE
       OF RATE
       ON ABC_PCD 
       REFERENCING NEW AS New OLD AS Old
       FOR EACH ROW
    DECLARE
      BEGIN
        UPDATE RM_TRAN_IN
        SET RATE = :NEW.RATE
        WHERE RM_PCD_ID = :NEW.RM_PCD_ID;
       EXCEPTION
         WHEN OTHERS THEN
           -- Consider logging the error and then re-raise
           RAISE;
    END ABC_RATE_UPD; here is my if condition, (edited)
    if :NEW.RATE != :OLD.RATE then
            UPDATE ABC_TRAN_IN
            SET RATE = :NEW.RATE
            WHERE ABC_PCD_ID = :NEW.ABC_PCD_ID;
        ELSIF :NEW.PACK_UNIT_ID != :OLD.PACK_UNIT_ID then
            UPDATE ABC_TRAN_IN
            SET PACK_UNIT_ID = :NEW.PACK_UNIT_ID
            WHERE ABC_PCD_ID = :NEW.ABC_PCD_ID;
    END IF;
        Its working good, is this a good approach, to the solution?
    regards:
    Edited by: user2040934 on Dec 29, 2012 3:22 PM

    In your trigger if you update more than one column at a time will it update all the updated columns in the other table properly?
    Can't you code something like this
    CREATE OR REPLACE TRIGGER ABC_RATE_UPD
    AFTER UPDATE
       OF col1,col2 , col3
       ON ABC_PCD 
       REFERENCING NEW AS New OLD AS Old
       FOR EACH ROW
    DECLARE
      BEGIN
    if updating ('col1') then
        UPDATE RM_TRAN_IN
        SET col1 = :NEW.col1
        WHERE :old.id = :NEW.id;
      end if;
      if updating ('col2') then
        UPDATE RM_TRAN_IN
        SET col2 = :NEW.col2
        WHERE :old.id = :NEW.id;
      end if;
       if updating ('col3') then
        UPDATE RM_TRAN_IN
        SET col3 = :NEW.col3
        WHERE :old.id = :NEW.id;
      end if;
       EXCEPTION
         WHEN OTHERS THEN
           -- Consider logging the error and then re-raise
           RAISE;
    END ABC_RATE_UPD;

  • After insert trigger issue

    Hi All,
    Can I have an after insert trigger on a table wherein the execution is also on the same table?
    It's like 10 columns in the table A.
    During a new row insertion, except one specific column(say 'J'), remaining all getting data.
    Now 'after insert', need to update the data of the column J based on one inserted value for column say ID.
    Code goes like below:
    CREATE OR REPLACE TRIGGER UPDATE_J
    AFTER INSERT ON A REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
    begin
    if :new.ID = 'N%' then
         :new.J:= 'N';
    else
         :new.J:= 'M';
    end if;
    end;
    Below is the error when I tried to execute that.
    ORA-04091: table string.string is mutating, trigger/function may not see it
    Cause: A trigger (or a user defined plsql function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.
    Action: Rewrite the trigger (or function) so it does not read that table.
    Any idea to resolve?
    Regards,
    Seetharaman.

    Hi,
    The docs say
    Restrictions on AFTER
          An AFTER row trigger or AFTER row section of a compound trigger can only read but not write into the :OLD or :NEW fields. When faced with problems like this, it is always a good thing to consult the documentation.
    Regards
    Peter

  • Servererror Trigger to mask ORA error

    When I place one tablespace offline, I get ORA-00376 and ORA-01110 errors. Ok, must return these errors same.
    The problem is that the ORA-01110 error shows the way of the archive of tablespace that is offline.
    I would like to mask this error through a servererror trigger.
    But errors 376 and 1110 together continue being shown with the message that I configured.
    Below it is my trigger.
    CREATE OR REPLACE TRIGGER check_tbs_status
    AFTER SERVERERROR ON DATABASE
    BEGIN
    if is_servererror(376) and is_servererror(1110) then
    raise_application_error(-20002,'TABLESPACE OFFLINE',true);
    end if;
    end;
    Suggestions?

    This was my last test, but if I to use only one of the errors, the same thing happens.
    Examples:
    CREATE OR REPLACE TRIGGER check_tbs_status
    AFTER SERVERERROR ON DATABASE
    BEGIN
    if is_servererror(1110) then
    raise_application_error(-20002,'TABLESPACE OFFLINE',true);
    end if;
    end;
    OR
    CREATE OR REPLACE TRIGGER check_tbs_status
    AFTER SERVERERROR ON DATABASE
    BEGIN
    if is_servererror(376)then
    raise_application_error(-20002,'TABLESPACE OFFLINE',true);
    end if;
    end;
    OR
    CREATE OR REPLACE TRIGGER check_tbs_status
    AFTER SERVERERROR ON DATABASE
    BEGIN
    if is_servererror(376) OR is_servererror(1110) then
    raise_application_error(-20002,'TABLESPACE OFFLINE',true);
    end if;
    end;
    OR with <raise_application_error(-20002,'TABLESPACE OFFLINE',FALSE);>
    In all cases the same thing happens.

  • Using Database Change Notification instead of After Insert Trigger

    Hello guys! I have an after insert trigger that calls a procedure, which in turn is doing an update or insert on another table. Due to mutating table errors I declared the trigger and procedure as autonomously transactional. The problem is, that old values of my main tables are inserted into the subtable since the after insert/update trigger is fired before the commit.
    My question is how can I solve that and how could I use the change notification package to call my procedure? I now that this notification is only started after a DML/DDL action has been commited on a table.
    If you could show me how to carry out the following code with a Database Change Notification I'd be delighted. Furthermore I need to know if it suffices to set up this notification only once or for each client seperately?
    Many thanks for your help and expertise!
    Regards,
    Sebastian
    declare
    cnumber number (6);
    begin
    select count(*) into cnumber from (
    select case when (select date_datum
        from
          (select f.date_datum,
            row_number() over (order by f.objectid desc) rn
          from borki.fangzahlen f
          where lng_falle      = :new.lng_falle
          and int_fallennummer = :new.int_fallennummer
          and lng_schaedling   = :new.lng_schaedling
          and date_datum       > '31.03.2010'
        where rn=1) < (select date_datum
        from
          (select f.date_datum,
            row_number() over (order by f.objectid desc) rn
          from borki.fangzahlen f
          where lng_falle      = :new.lng_falle
          and int_fallennummer = :new.int_fallennummer
          and lng_schaedling   = :new.lng_schaedling
          and date_datum       > '31.03.2010'
        where rn=2) then 1 end as action from borki.fangzahlen
            where lng_falle      = :new.lng_falle
            and int_fallennummer = :new.int_fallennummer
            and lng_schaedling   = :new.lng_schaedling
            and date_datum       > '31.03.2010') where action = 1;
    if cnumber != 0 then
    delete from borki.tbl_test where lng_falle = :new.lng_falle
    and int_fallennummer = :new.int_fallennummer
    and lng_schaedling   = :new.lng_schaedling
    and date_datum       > '31.03.2010';
    commit;     
    pr_fangzahlen_tw_sync_sk(:new.lng_falle, :new.int_fallennummer, :new.lng_schaedling);

    It looks like you have an error in line 37 of your code. Once you fix that the problem should be resolved.

  • FND_REQUEST.SUBMIT_REQUEST is not working in After Report Trigger Reports6i

    Hi Guys,
    I am calling the another conc program in After report trigger using FND_REQUEST.SUBMIT_REQUEST. The below are the statement which i use in my program.
    req_id := FND_REQUEST.SUBMIT_REQUEST('APPL_SHORT','CONC_SHORT',NULL,NULL,FALSE);
    I have also use the SRW.USER_EXIT('FND SRWINIT') in Before Report Trigger and SRW.USER_EXIT('FND SRWEXIT') in After Report Trigger also.
    I am getting the error in Log file saying that
    REP-0736: There exist uncompiled program unit(s).
    REP-1247: Report Contains uncompiled PL/SQL.
    Quick Response is highly appreciated.
    Thanks in Advance.
    Regards
    Madhan.S

    Hi Sawwan,
    I was compiled in Unix platform also. If i comment that FND_REQUEST.SUBMIT_REQUEST line it executes fine. It gives the same error in Unix also.
    Can anyone pls help this issue.
    Thanks in Advance.
    Regards
    Madhan.S

Maybe you are looking for

  • New Thunderbolt to FireWire

    Does anyone know when apple is going to release the Thunderbolt to FireWire adapter and what kind of FireWire it will be? I have an old video camera with a 4-pin FireWire 400 and I have the new MacBook Pro Retnia Display which doesn't have FireWire.

  • Anyone have their Touch hooked up to a Panasonic Car Stereo?

    I have my Touch scheduled to deliver on Monday and I currently get the most out of my current 5G Video iPod in the car which is hooked up to my Panasonic Car Stereo that is iPod compatible. I have tried to ask Panasonic if their current and past ster

  • Premier Elements 11 Won't Open!

    Hi! I am running a HP Personal Computer with Windows 7. I have been using Elements 11 for months without problem and have been very pleased with the product. I went to open it today and was unable to. It would not load past the "Welcome Screen," whic

  • How to clear cache in firefox

    how to clear cache in firefox

  • Windows 8.1 not seeing USB drive on router

    hi if use windows 7 i can acess my router usb drive but when use windows 8.1 cannot see it but if i do that Control Panel - Administrative Tools - Local Security Policy Local Policies - Security Options Network security: LAN Manager authentication le