Auditing tables - standard way of recording changes to db

Hi,
This is a general query that i would like to know how others handle.
We run a forms based system and use within the database a createby, createdate, amendby, amenddate column policy were on a pre insert, pre update the fields are populated. But obviosely this does not tell us which fields where changed from what to what only that something on the table was inserted/updated.
So we extended further and wrote some triggers on key fields to make a note of before and after changes using a seperate table to store the values.
I think this is messy and often requires a lot of specific coding to be done. I was wondering how other developers handled auditing of data within their applications. In an ideal world we would have something quite generic whereby we did not need to amend code on each trigger we wrote but i know this is unlikely!
General opinions on the best solution/standards to use would be a great help
Thanks

Instead of reinventing the wheel, you could indeed use standard features like Fine Grained Auditing for that purpose:
BEGIN
  dbms_fga.add_policy(
  object_schema =>   'HR',
  object_name =>     'EMPLOYEES',
  policy_name =>     'my_policy',
  statement_types => 'SELECT,INSERT,UPDATE,DELETE');
END;Above example puts a FGA policy on the employees table that protocols into the fga_log$ table owned by sys and accessible via DBA_FGA_AUDIT_TRAIL
You can easily test this for your table also and see, whether this gets you what you need, which I would assume.
Kind regards
Uwe
http://uhesse.wordpress.com

Similar Messages

  • Is it possible to records another machine ip addree in audit table

    Hai
    I have written system event trigger,it records username, ip address and time in audit table when user logged on database , The database reside on xx machine ( 10.0.0.88 ipaddess ). Is it possible to records another machine ip addree in audit table while accessing database from another machine?
    example we have another database on xxx machine (10.0.0.2 ip address),when accessing database from xxx(10.0.0.2) to xx (10.0.0.88),the xxx node ip address will be stored in audit table?.
    Thanks in advance
    Regards
    mohan
    CREATE OR REPLACE TRIGGER On_Logon
    AFTER LOGON
    ON database
    declare
    db_name VARCHAR2(50);
    addr varchar2(80);
    x varchar2(20);
    begin
    db_name := ora_database_name;
    select utl_inaddr.get_host_address into x from dual;
    if ( ora_sysevent ='LOGON')
    then x:=utl_inaddr.get_host_address;
    insert into log1
    select ora_sysevent,ora_login_user,ora_database_name,utl_inaddr.get_host_address,sysdate
    from dual;
    end if;
    end;
    SQL> select * from log1;
    OPERATION USERNAME DATABASE IP_ADDR TIME
    LOGON MOHAN1 ISOLA6.US.ORACLE.COM 10.0.0.88 11-APR-02
    Based on system events trigger how to find out which user from which machine (ip address) accesing database?
    example:
    CREATE OR REPLACE TRIGGER On_Logon
    AFTER LOGON
    ON database
    declare
    db_name VARCHAR2(50);
    addr varchar2(80);
    x varchar2(20);
    begin
    db_name := ora_database_name;
    select utl_inaddr.get_host_address into x from dual;
    if ( ora_sysevent ='LOGON')
    then x:=utl_inaddr.get_host_address;
    insert into log1
    select ora_sysevent,ora_login_user,ora_database_name,utl_inaddr.get_host_address,sysdate
    from dual;
    end if;
    end;
    SQL> select * from log1;
    OPERATION USERNAME DATABASE IP_ADDR TIME
    LOGON MOHAN1 ISOLA6.US.ORACLE.COM 10.0.0.88 11-APR-02

    Providing you're on 8i+ this will give you the IP address from which th eclient is connected:
    SELECT sys_context('userenv', IP_ADDRESS) FROM dual;
    Bear in mind that many network applications assign IP Addresses dynamically, so depending on how your network is segmented, the same machine can have very different IP addresses from day to day. If this is just an internal system you're auditing then you might find this call more useful:
    SELECT sys_context('userenv', TERMINAL) FROM dual;
    This returns the network's ID for the machine, and this is non-varying (unless network admin change it explicitly - but why would they?). This call is also available in the older, deprecated USERENV function:
    SELECT userenv('TERMINAL') FROM dual;
    rgds, APC

  • How to maintain previous and record count in audit table in SQL Server 2008 r2?

    Hi Experts ,
     Situation :
    in our database we are having few of stored procedures which will drop and recreates the tables and it is scheduled on weekly basis. when this job will run all the stored procedures will drop all the tables and recreate. Now we need to create one table which
    will maintain history of the records.
    my table structure is listed below
    TableName CurrentReocrdCount CurrentExecutionDate PreviousReordCount PreviousExurtiondate
    TEST         1000                   2014-03-30            NULL        NULL
    Test         1500                   2014-04-10            1000      2014-03-30
    Test         2000                   2014-04-11            1500      2014-04-10 
    How do i achive this . 
    franklinsentil

    You need to create audit tables for these. The table will be populated by COUNT value inside stored procedure. Each time it clears the main table and fills new data and also logs count details to audit tables. You can use COUNT(*)  to get count value
    and GETDATE function to get current execution value.
    So proc will look like
    CREATE PROC procname
    @param....
    AS
    --step to drop existing table
    IF OBJECT_ID('tablename') IS NOT NULL
    DROP TABLE <table name>
    --step to fill new table
    SELECT ...
    INTO TableName
    FROM
    --Audit table fill step
    INSERT AuditTable (TableName,CurrentRecordCount,CurrentExecdate,PrevRecordCount,PrevExecDate)
    SELECT TOP 1 'TableName',(SELECT COUNT(*) FROM tableName),GETDATE(),CurrentRecordCount,CurrentExecDate
    FROM AuditTable
    ORDER BY CurrentExecDate DESC
    UNION ALL
    SELECT 'TableName',(SELECT COUNT(*) FROM tableName),NULL,NULL
    WHERE NOT EXISTS (SELECT 1 FROM AuditTable)
    GO
    Please Mark This As Answer if it helps to solve the issue Visakh ---------------------------- http://visakhm.blogspot.com/ https://www.facebook.com/VmBlogs

  • Any standard table that keep tracks of changes in user attributes

    Hi,
    We have a HR system and we are tyring to find out a standard table that keep tracks of changes(when was it changed,who changed it,what has been changed) in user details like email,address etc.
    Plz let me know the solution
    Thanks
    Bala Duvvuri

    CDHDR
    CDPOS

  • Need to create a audit table column change wise

    Is it possible to know which column value has been change? when ? by which operation(insert,update,delete) ?
    have any view or trigger?
    MY sample audit table like
    CREATE TABLE CHANGE_TRACK
    SERIAL NUMBER NULL,
    TABLE_NAME VARCHAR2(100 BYTE) NULL,
    COLUMN_NAME VARCHAR2(100 BYTE) NULL,
    COLUMN_VALUE VARCHAR2(1024 BYTE) NULL,
    CHANGE_TIME DATE NULL,
    OPERATION_TYPE VARCHAR2(20 BYTE) NULL
    Thanks
    Halim

    I have found my solution here
    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:59412348055
    Thanks
    Halim

  • Audit tables population

    I am working on Oracle 9i database and having nearly 100 tables of 15 columns each on average.
    We have two seperate tables for Audit purpose. First table contains only table name which got effected by updates and deletes. Second table contains first table's Id, column name, old value and new value.
    If value of one column of a table changes, it would be one record in each audit table. If values of 20 columns are updated then one record in the first table and 20 records in the second table with old and new values.
    Please help me out the best way to accomplish this task.
    Thanks for the help.

    Because I don't know which column is being updated by user.Yes you do.
    SQL> set serveroutput on
    SQL> create or replace trigger trig_emp2_insupd
      2  before insert or update
      3  on emp2
      4  for each row
      5  begin
      6    if (UPDATING('ENAME'))
      7    then
      8      dbms_output.put_line('Ename is updated') ;
      9    end if ;
    10    if (UPDATING('SAL'))
    11    then
    12      dbms_output.put_line('Sal is updated') ;
    13    end if ;
    14  end ;
    15  /
    Trigger created.
    SQL> update emp2 set ename = null where rownum < 2 ;
    Ename is updated
    1 row updated.
    SQL>
    SQL> update emp2 set sal = null where rownum < 2 ;
    Sal is updated
    1 row updated.
    SQL>
    SQL> update emp2 set sal = null, ename = null where rownum < 2 ;
    Ename is updated
    Sal is updated
    1 row updated.
    SQL>

  • Is it possible to create a view where table in the From clause changes name

    is it possible to create a view from a from a table like this
    create view my_view as select id, col1, col2, result from <<my_latest_cacahe_table>>;
    the table in the from clause changes the name .
    I have another table which indicates the the latest name of my cache tables. Always there are two records there. The latest one and previous one.
    select * from cache_table_def
    table_name cache_table_name refresh_date
    my_table cache_table245 1/23/2012
    my_table cache_table235 1/22/2012
    create table cache_table_def (table_name varchar2(25), cache_table_name varchar2(25), refresh_date date);
    insert into cache_table_def values( 'my_table','cache_table245','23-jan-2012');
    insert into cache_table_def values ( 'my_table','cache_table546','22-jan-2012');
    create table cache_table245 (id number, col1 varchar2(50), col2 varchar2(20), result number);
    insert into cache_table245 values(1, 'test123', 'test345',12.12);
    insert into cache_table245 values (2, 'test223', 'test245',112.12);
    create table cache_table235 (id number, col1 varchar2(50), col2 varchar2(20), result number);
    insert into cache_table235 values (1, 'test123', 'test345',92.12);
    insert into cache_table235 values (2, 'test223', 'test245',222.12);
    what I need to do is find the latest cache_table name for my_table and use that in my view defintion
    When user select from the the view it always reurns the data from the latest cache_table
    is it possible to do something like this in oracle 11g?
    I have no control on the cache tables names. that is why I need to use the latest name from the table.
    Any ideas really appreciated.

    I've worked up an example that does what you ask. It uses the SCOTT schema EMP table. Make two copies of the EMP table, EMP1 and EMP2. I deleted dept 20 from emp1 and deleted dept 30 from emp2 so I could see that the result set really came from a different table.
    -- create a context to hold an environment variable - this will be the table name we want the view to query from
    create or replace context VIEW_CTX using SET_VIEW_FLAG;
    -- create the procedure specified for the context
    - we will pass in the name of the table to query from
    create or replace procedure SET_VIEW_FLAG ( p_table_name in varchar2 default 'EMP')
      as
      begin
          dbms_session.set_context( 'VIEW_CTX', 'TABLE_NAME', upper(p_table_name));
      end;
    -- these are the three queries - one for each table - none of them will return data until you set the context variable.
    select * from emp where 'EMP' = sys_context( 'VIEW_CTX', 'TABLE_NAME' );
    select * from emp1 where 'EMP1' = sys_context( 'VIEW_CTX', 'TABLE_NAME' );
    select * from emp2 where 'EMP2' =  sys_context( 'VIEW_CTX', 'TABLE_NAME' )
    -- this is how you set the context variable depending on the table you want the view to query
    exec set_view_flag( p_table_name => 'EMP' );
    exec set_view_flag( p_table_name => 'EMP1' );
    exec set_view_flag( p_table_name => 'EMP2');
    -- this will show you the current value of the context variable
    SELECT sys_context( 'VIEW_CTX', 'TABLE_NAME' ) FROM DUAL
    -- this is the view definition - it does a UNION ALL of the three queries but only one will actually return data
    CREATE VIEW THREE_TABLE_EMP_VIEW AS
    select * from emp where 'EMP' = sys_context( 'VIEW_CTX', 'TABLE_NAME' )
    union all
    select * from emp1 where 'EMP1' = sys_context( 'VIEW_CTX', 'TABLE_NAME' )
    union all
    select * from emp2 where 'EMP2' =  sys_context( 'VIEW_CTX', 'TABLE_NAME' )
    -- first time - no data since context variable hasn't been set yet
    SELECT * FROM THREE_TABLE_EMP_VIEW
    -- get data from the EMP table
    exec set_view_flag( p_table_name => 'EMP' );
    SELECT * FROM THREE_TABLE_EMP_VIEW
    -- get data from the EMP2 table
    exec set_view_flag( p_table_name => 'EMP2');
    SELECT * FROM THREE_TABLE_EMP_VIEW
    For your use case you just have to call the context procedure whenever you want to switch tables. You can union all as many queries as you want and can even put WHERE clause conditions based on other filtering criteria if you want. I have used this approach with report views so that one view can be used to roll up report data different ways or for different regions, report periods (weekly, quarterly, etc). I usually use this in a stored procedure that returns a REF CURSOR to the client. The client requests a weekly report and provides a date, the procedure calculates the START/END date based on the one date provided and sets context variables that the view uses in the WHERE clause for filtering.
    For reporting it works great!                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Table capturing info regarding PR00 Changes

    hi all,
    my client wants a report which shows the Change in Basic Price PR00 for a period and user(who have changed).
    how this can be achieved... is there any standard table which captures these info..
    please guide..
    thank u..
    pearl.

    sorry, did not get the question correctly.
    Check this -
    Re: condition record change report
    - Try the AUT10
    Edited by: Samit C on Mar 14, 2011 4:32 PM

  • Auditing tables..

    Hi Experts,
    Could anyone help me with the following issue.
    we are trying to implement the "audit feature" on a table. what is the best way to do the audit? (keep track of all the changes in the table)
    This is what we are doing..
      Main_table
      id
      first_name
      last_name
       dob
      hire_date
      created_date
      created_by
      updated_date
      updated_by
      audit_table
      ad_action (whether it is insert,update or delete)
      ad_time (time)
      ad_user (whos is the user)
      id
      first_name
      last_name
       dob
      hire_date
      created_date
      created_by
      updated_date
      updated_by
    and i have a trigger on the "main_table" like this
      CREATE OR REPLACE TRIGGER Main_table_AIUD after
    insert or update or delete on Main_table for each row
    begin
       declare
          ljn_action varchar2(3);
       begin
          if inserting then
             ljn_action := 'INS';
          elsif updating then
             ljn_action := 'UPD';
          else
             ljn_action := 'DEL';
          end if;
          if inserting  then
             insert into audit_table
              ad_action,
              ad_time,
              ad_user,
              id
              first_name
             last_name
             dob
             hire_date
             created_date
             created_by
             updated_date
             updated_by
             values
              ljn_action
             ,sysdate
             ,nvl(v('APP_USER') ,USER)
             :new.id,
            :new.first_name,
             :new.last_name,
              :new.dob,
             :new.hire_date,
             :new.created_date,
             :new.created_by,
             :new.updated_date,
              :new.updated_by
          elsif updating then
            insert into audit_table
              ad_action,
              ad_time,
              ad_user,
              id
              first_name
             last_name
             dob
             hire_date
             created_date
             created_by
             updated_date
             updated_by
             values
              ljn_action
             ,sysdate
             ,nvl(v('APP_USER') ,USER)
             :old.id,
            :old.first_name,
             :old.last_name,
              :old.dob,
             :old.hire_date,
             :old.created_date,
             :old.created_by,
             :old.updated_date,
              :new.updated_by
          else
             insert into audit_table
              ad_action,
              ad_time,
              ad_user,
              id
              first_name
             last_name
             dob
             hire_date
             created_date
             created_by
             updated_date
             updated_by
             values
              ljn_action
             ,sysdate
             ,nvl(v('APP_USER') ,USER)
             :old.id,
            :old.first_name,
             :old.last_name,
              :old.dob,
             :old.hire_date,
             :old.created_date,
             :old.created_by,
             :old.updated_date,
              :new.updated_by
          end if;
       end;
    end;
    /For "Insert" and "Delete" as i need to capture all the elements my code would be ok.
    But for "update" how can i capture only the columns that got changed? and put it in the audit table
    so next time if i go to the audit table i can clearly see that these elements got changes.
    Is there any better way to do this?
    Please let me know
    Thanks

    Yeah for tracking OLD and NEW values you have to write a trigger.
    Your trigger code seems fine except a few quirks.
    You audit_table should contain two fields against each column of the main table. e.g. for first_name column in main_table there should be two fields old_firstname and new_firstname in the audit_table.
    And then each section of trigger (inserting, updating, deleting) insert both :OLD and :NEW values to the table. In case of INSERT there will be no :OLD values so just insert NULL and in case of DELETE there will be no :NEW values so insert NULL. But in case of UPDATE its important to track both :NEW and :OLD.
    and if you track both NEW and OLD values in the trigger and put them in the audit_table then you no longer need to identify which columns are changed. You can figure that later on when you query the audit_table, any fields where OLD and NEW values are same was not updated.
    If you still want to check which column was changed in the trigger, refer to Himanshu Kandpal's post above.
    And you probably don't need this code in the trigger:
          if inserting then
             ljn_action := 'INS';
          elsif updating then
             ljn_action := 'UPD';
          else
             ljn_action := 'DEL';
          end if;You can Just use the values 'DEL','INS' and 'UPD' where appropriate instead of the ljn_action variable.

  • How to Query the Audit Tables

    Our Production system is suffering performance issues which we attribute to the large volume of records in the audit tables. We want to implement an archival solution to alleviate this, which would involve transferring older audit records to a separate database. To achieve this, we need to write SQL queries against the <app>DATAAUDIT and <app>TASKAUDIT tables in the HFM database. We are aware that we need to join other tables to see descriptions, e.g. <app>SCENARIODESC. We have also deduced the translation of Activity Codes from "HFMAuditExtractSchemaDefs.xml", which accompanies the HFM Audit Extract Utility.
    Unfortunately, there are some things which we do not know how to translate:
    1) Period (lPeriod) on the <app>DATAAUDIT table, e.g. 67108869 but need to show "Jun" etc.
    2) User (ActivityUserId) on the <app>TASKAUDIT table, e.g. -329543984
    3) Module (strModuleName) on the <app>TASKAUDIT table, e.g. #@RID@#19
    Can anyone advise how we should translate these pieces of data in order to give similar results to those seen on the Data Audit and Task Audit screens in Workspace?

    1.) Period - I'm not sure where this is coming from, but I'm pretty confident it is not sitting in the database which I find odd. I want to find this as well, but haven't had any free time to search around, sorry.
    2.) User - This one I can help you with.
    --Get Task Item Data by Hour for a given day by user
    select datepart(HOUR, cast(endtime-2 as smalldatetime)), count(activitycode) from <APP_NAME>_task_audit where activitycode in (1,4,6,8,9,12,14,15,16,21,23,44) and cast(endtime-2 as smalldatetime) between '2011-12-7 00:00:00' and '2011-12-7 23:59:59' and ActivityUserID in (select lUserID from HSV_ACTIVITY_USERS where sUserName = '<USER_NAME>') group by datepart(HOUR, cast(endtime-2 as smalldatetime))In the sample SQL Query above, I am looking for all of the task audit activity (for the specified tasks) for a specific user by hour. The part of the query you want to focus on is
    and ActivityUserID in (select lUserID from HSV_ACTIVITY_USERS where sUserName = '<USER_NAME>')The ActivityUserID in the task audit table will match up to the lUserID field in the HSV_ACTIVITY_USERS table. sUserName will be the actual text username. Depending on how you are configured, the name may look like johndoe or johndoe@Native Directory or johndoe@AD, etc. If you query that table, you'll figure it out pretty quickly.
    3.) Module ID. I can only partially assist on this one.
    This is not also in the HFM database. I suspected it might be floating in workspace; however, can't really find it there either.
    I can tell you a couple things though....
    #@RID@# Is just a placeholder for Resource ID. The important part is the number behind it. If you do a search on your folders for @RID@, you'll get one hit where it is defined as a constant, but that is it. (I was hoping a file search would reveal a table of the ID's; however, I wasn't that lucky). There is probably a table of values that correspone somewhere, but I haven't found it.
    If you do a distinct select, you'll see there's not too many ...
    select distinct strmodulename from <APP_NAME>_task_audit#@RID@#10
    #@RID@#13
    #@RID@#14
    #@RID@#16
    #@RID@#18
    #@RID@#23
    #@RID@#30
    #@RID@#32
    #@RID@#4294967295
    #@RID@#45
    #@RID@#46
    #@RID@#49
    #@RID@#52
    #@RID@#58
    #@RID@#59
    #@RID@#65
    #@RID@#66
    #@RID@#67
    #@RID@#68
    #@RID@#69
    #@RID@#7
    #@RID@#9
    HyperionReports
    How can you determine these values?
    The quick and dirty way would be to run a Task Audit Extract for a given date range as this will reveal the Module Name.
    Then execute a SQL Query on the Task Audit Table for the same data range. You could then match up the records and deduce the values.
    --Get Task Items by Date Range
    select (select sUserName from HSV_ACTIVITY_USERS where lUserID = ActivityUserID) as UserName, ActivityCode, ServerName, AppName, cast(StartTime-2 as smalldatetime), cast(EndTime-2 as smalldatetime), strDescription, strModuleName from <APP_NAME>_task_audit where cast(endtime-2 as smalldatetime) between '2011-12-7 00:00:00' and '2011-12-7 23:59:59' order by endtime ascOnce you determine the values, I would create a table in your database to hold them so that you could use them in future queries. I would also recommend you do the same with the activitycodes.

  • Dynamic internal table ( make one internal table parts of the record )

    hello i am doing a program that look for document billing put it in a internal table then loop the internal table and use the FM SD_DOCUMENT_FLOW_GET for get the document flow that fm return a table and i need make every record of that table part of the currect register , i already do this in a ugly static way but i am looking a dynamic way of do this , i know that the ABAP OO is the way but i am no able to get this approarch ( i am noob in abap and any experience with OO programing )
    i will show the code for better understanding of it
    pd: is a crappy code i know sorry
    [CLick Here for the see the Code ( pastebin )|http://linuxlatino.pastebin.com/m39120e69]

    thanks all for the answer , but i will try explain better my problem :
    i have a it_data interntal table with document bill record i do a loop to that table and used the vbeln field in the FM for get the docment flow of that document billing number now the output of the FM is a table and i need take each record of that table am make it part of the current record of it_Data.
    Example:
    it_Data without the it_docflow data
    *Sales ORg*   *Distri.Channel*      *Billing Type*    *Payer*         *Sold-to-party*        vbeln*
    TP01         C1                     ZT17           1000524     1000524                 85003435 ..........
    it_docflow table ( FM Output ):
    *DOCNUM     ITEMNU    DOCNUV    ITEMNU            Description*
    53107842   000000                          000000         Standard Order
    65004606   000000       53107842   000000        Outbound Delivery
    75179356   000000      65004606   000000         Invoice
    57000118   000000      75179356   000000        Returns
    85003435   000000      57000118   000000        Credit for Returns
    5200003681 000000     85003435   000000       Accounting Doc.
    now the it_docflow data add in the it_data record:
    53107842  Standard Order  65004606 Outbound Delivery 75179356  Invoice  57000118 Returns  85003435 Credit for Returns 5200003681 Accounting Doc   TP01         C1                     ZT17           1000524     1000524                 85003435 .........
    i hope this explain better my problem here , thanks again

  • Modifying OWB audit tables?

    One option we are exploring on a new project is using the OWB audit tables/views as control tables to facilitate extracting changed data from the source system.
    For example
    Extract all data from source table x where update_date > (select max(start_time) from all_rt_audit_map_runs where map_name = y and run_status = 'COMPLETE')
    I am no terribly keen on the idea. Has anyone done this in the past? Would you consider this standard practice? I'd prefer to maintain our own control table(s).
    One problem I see is that (especially in dev/testing environments) it would call for situations where there needs to be manual modification of the data in OWB audit tables, which may lead to the data in them becoming corrupt. Would updating things like start_time, end_time and run_status be an acceptable development practice? I just think that once you start updating a table like all_rt_audit_map_runs it becomes very difficult to keep corresponding tables like ALL_RT_AUDIT_STEP_RUNS also accurate.
    Would appreciate others thoughts on the matter.

    I'd suggest maintaining your own tables, they are then in your control, there is no guarantee that the OWB audit tables will be in the same format in future releases.

  • Database trigger to insert duplicated rows on audit table

    Hi
    It is possible to insert duplicate rows (at the moment database generate PK violation constraint for one specific table) within an audit table ?
    Certain code like this is not working, always the whole transaction makes a rollback and audit table will be empty:
    CREATE OR REPLACE TRIGGER USER.audit_TABLE_TRG
    before INSERT ON USER.TABLE
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
    BEGIN
    declare
    V_conteo number(1) := 0;
    duplicate_record EXCEPTION;
    begin
    select count(*)
    into V_conteo
    from USER.TABLE
    where <PK conditions>
    if V_conteo > 0 then
    begin
    INSERT INTO USER.AUDIT_TABLE
    (<>)
    VALUES
    (<>);
    raise duplicate_record;
    exception
    when duplicate_record then
    INSERT INTO USER.AUDIT_TABLE
    (<>)
    VALUES
    (<>);
    raise_application_error(-20019,'Duplicated column1/column2:'||:NEW.column1||'/'||:NEW.column2);
    when others then
    dbms_output.put_line('Error ...'||sqlerrm);
    end;
    end if;
    end;
    END;
    /

    >
    Exactly this is my problem , one only transaction (insert into audit table and try to insert into target table), the reason of this post is to know whether exists another way to insert all the intent duplicate records on target table into one audit table, you right ,maybe I can add one date column and modify the PK on audit table but my main problem still happens.
    >
    Can I ask you why you want to go trigger route for this if your intention is only to capture the duplicate records? Assuming that you are on at least on 10gR2, you can look at DML error table. If you go this route, there is no need for additional overhead of trigger, code failures, etc.
    Oracle can automatically store the failed records in an error table which you could later on investigate and fix it or ignore it.
    Simple example:
    SQL> create table emp (empno number primary key, ename varchar2(10), sal number);
    Table created.
    SQL> insert into emp values(1010, 'Venkat', 100);
    1 row created.
    SQL> commit;
    Commit complete.
    Create error table to log the failed records
    BEGIN
          DBMS_ERRLOG.create_error_log (dml_table_name => 'emp');
    END;
    Now let's insert a duplicate record
    SQL> insert into emp values(1010, 'John', 200) ;
    insert into emp values(1010, 'John', 200)
    ERROR at line 1:
    ORA-00001: unique constraint (VENKATB.SYS_C002813299) violated
    Now use the log table to capture
    SQL> insert into emp values(1010, 'John', 200) LOG ERRORS INTO err$_emp ('INSERT') REJECT LIMIT UNLIMITED;
    0 rows created.
    Now check the error log table and do whatever you want
    SQL> r
      1* select ORA_ERR_MESG$, empno, ename, sal from err$_EMP
    ORA_ERR_MESG$
    EMPNO
    ENAME
    SAL
    ORA-00001: unique constraint (VENKATB.SYS_C00
    2813467) violated
    1010
    John
    200
    1 row selected.This will also capture when you do
    INSERT INTO EMP SELECT * FROM EMP_STAGE LOG ERRORS INTO err$_emp ('INSERT') REJECT LIMIT UNLIMITED;
    You can capture the whole record into the log table. All columns.
    Regards
    Edited : Code

  • Maintaining an Audit Table

    Hi - I have created a small country table with country cd, country name and some audit columns like updt timestamp, updt cd etc. I edited the doDML() method of cntryImpl.java to auto populate some of the audit information.
    and generated the JHeadstart webpages.
    If I want to add another table like an audit table, which will maintain all the inserts, deletes, updates made to the actual country table, how do I do that ?
    That is, any row added to the country table via the default webpages, should also add a row in this audit table. Any deletes in the actual table, should insert a record in the audit table with updt type cd 'delete'. How do I go about this?

    You have several options:
    1. Create audit tables in the database and have them filled with triggers. I believe good-old Headstart utilties (not to be confused with JHeadstart) can automate this proces. No java coding needed
    2. Or you want to implement this in business components. I would recommend building a generic solution in the entityImpl superclass in the doDML method. Perhaps it is good idea to have a generic audit table in which changed values are stored in XML format, so you do not need to create shadow tables for every table of your application you want to implement auditing for.

  • Standard way of implementing different timezones.

    Wanted to know the standard way of implementing timezones for an international web application.
    I have the different companies information in a table called company.
    Is it a good idea to store the timeoffset from GMT in the database or create a new table timzone and link this table with the company table.

    The decorator pattern was meant for this =). Look it up; I believe you will find it useful. You can use the decorator pattern with your Weapons.
    Enums do make sense, since the weapon types will be considered constants. Just to let you know, 2D arrays are really only useful for data structures that have a finite 2D shape, such as those found in tictactoe programs. I'd suggest that you look into the topic of data structures sometime.
    I think that a better way to implement the attacking system would be to have the Weapon object do the damage itself -- assign the logic to the object that contains the data necessary to carry out the logic. This way the program is more modular and setter/getter requests, which threaten the maintenance of a program (changes in implementation will ripple throughout), are avoided. (If the player is to carry out the task of doing the attacking, it will have to retrieve information from the weapon. And if all the Weapon objects do is store Weapon-related information, then they're weak objects and it's a clue that you're giving their responsibility to other objects when you shouldn't be.) I would go would this idea.
    Now that I think more about it, your player class could interpret input from the UI (or do stuff based on UI-generated events) and create the appropriate weapon and have the weapon do the damage/attacking itself, as I described above.

Maybe you are looking for

  • Problem with store ResultSet and show result in table

    Hi, I'm kind of new in ADF, I need to store ResultSet and show result in table-component. I have two problems: 1) I get my ResultSet by calling callStoredProcedure(...) and this returns actually ref_cursor as ResultSet. When I try to println() contai

  • Form won't distribute. Here's the error and everything I've tried so far. Hope you can help

    I've seen at least 2 similar posts on the web, but they ended with no answer. After creating my form with LiveCycle Designer, saving as pdf, and hitting "DISTRIBUTE", I get this error: "The filename you specified is not valid because it does not incl

  • Display of condition record for PPF actions

    Hi, Standard ECC functionality provides the option to view the condition record considered for relevant condition type in sales order etc . Please inform whether I can see the PPF condition record in similar way for relevant documents like IBD , ODO

  • Print Event Details (absorbed into convert to PDF)

    Hi All, i want to print events list into a PDF document please help me how to do that.It is very urgent.Please give me reply immediately. Anybody have code please send me.. Thanks in advance.......

  • Unable to connect JavaDB

    I created a database in derby (with ij tool). I wanted to connect this database through JSP page from Tomcat 6 server. I started the Network Server from Command Window(Server Shell) Server started (used 1527 port) I connected the created database by