Skip to Main Content
  • Questions
  • capture old and new values of the fields using Stored Procedure

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Ankit.

Asked: September 15, 2017 - 10:27 am UTC

Last updated: September 18, 2017 - 12:51 pm UTC

Version: 12.1.0

Viewed 10K+ times! This question is

You Asked

Hi,

We have a requirement to store old and new values of the fields and insert into another table.

For example,

If we have Table A and Table B and in both the tables columns are exactly same but we need to write a procedure like whenever any fields' values get changed in table A. Both old and new values will be inserting into table B. Also if any new entry is made in table A that should also capture in table B and if any record has been deleted from table A then also it should capture in table B.

In short, if all DML operations have made on table A, everything should capture in table B using stored procedure.

could you please suggest any example to fulfill above scenario?

Please let me know if require more details.

Thanks.

and Connor said...

I would look at Flashback Data Archive for this.

Chris has quick intro video here



and Tim Hall has some scripts to get you up an running

https://oracle-base.com/articles/11g/flashback-and-logminer-enhancements-11gr1#flashback_data_archive


Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

followup

A reader, September 18, 2017 - 2:46 am UTC

thanks chris but this I don't want. the requirement is there are 2 tables A & B,

Table A
emp_id | emp_name |dept_id |salary
1 | A | 10 | 1000
2 | B | 20 | 2000
3 | C | 30 | 3000
4 | D | 40 | 4000

Table B
Emp_id |emp_name|dept_id|salary|Old_value|New_value

Now, any of the record has been changed(update existing record, Add new records and delete existing record) from Table A, old and new values should be inserted into Table B at the time of changing the value in Table A without using trigger.

Please suggest, is it possible.

Thanks.
Chris Saxon
September 18, 2017 - 12:50 pm UTC

If you don't want to use Flashback Data Archive or triggers, then you're going to have to write your own code.

The example below from Fahd Bahoo should help you get started.

Review for Ankit

Fahd Bahoo, September 18, 2017 - 7:30 am UTC

Hi Ankit,
Solution given by Connor is no code solution. Any thing that can be done without code is better (less code = less bugs). Any way this might help you.

create Table A
(emp_id number(5) PRIMARY KEY,
emp_name varchar2(30),
dept_id number(2),
salary number(5) )
/
CREATE Table B
(emp_id number(5),
emp_name varchar2(30),
dept_id number(2),
salary number(5),
Old_value number(5),
New_value number(5),
action VARCHAR2(10) )
/
insert into A
values (1 , 'A' , 10 , 1000);
insert into A
values (2 , 'B' , 20 , 2000);
insert into A
values (3 , 'C' , 30 , 3000);
insert into A
values (4 , 'D' , 40 , 4000);
COMMIT
/
CREATE OR REPLACE PROCEDURE INSERT_A(
  emp_id_in A.emp_id%type, 
  emp_name_in A.emp_name%type, 
  dept_id_in A.dept_id%type,
  salary_in A.salary%type)
IS
BEGIN
  insert into a(emp_id, emp_name, dept_id, salary)
  values(emp_id_in, emp_name_in, dept_id_in, salary_in) ; 
  
  insert into b(emp_id, emp_name, dept_id, salary,Old_value,new_value, action)
  values(emp_id_in, emp_name_in, dept_id_in, salary_in,null, salary_in, 'INSERT') ;  
END;
/
begin
  insert_a(5,'E',50,'5000');
end;
/
select * from a ;
select * from b ;
/
CREATE OR REPLACE PROCEDURE update_A(
  emp_id_in A.emp_id%type, 
  salary_in A.salary%type)
IS
l_emp_name A.emp_name%type ;
l_dept_id A.dept_id%type ;
l_salary A.salary%type ;
BEGIN
  SELECT emp_name, dept_id, salary
  into  l_emp_name, l_dept_id, l_salary
  from A
  where emp_id = emp_id_in 
  for update;
   
  update a
  set salary = salary_in 
  where emp_id = emp_id_in ;
  
  insert into b(emp_id, emp_name, dept_id, salary,Old_value,new_value, action)
  values(emp_id_in, l_emp_name, l_dept_id, l_salary,l_salary, salary_in, 'UPDATE') ;  
END;
/
begin
  update_a(5,'6000');
end;
/
select * from a ;
select * from b ;

CREATE OR REPLACE PROCEDURE delete_A(
  emp_id_in A.emp_id%type )
IS
l_emp_name A.emp_name%type ;
l_dept_id A.dept_id%type ;
l_salary A.salary%type ;
BEGIN
  SELECT emp_name, dept_id, salary
  into  l_emp_name, l_dept_id, l_salary
  from A
  where emp_id = emp_id_in 
  for update;
   
  delete from a 
  where emp_id = emp_id_in ;
  
  insert into b(emp_id, emp_name, dept_id, salary,Old_value,new_value, action)
  values(emp_id_in, l_emp_name, l_dept_id, l_salary,l_salary, NULL, 'DELETE') ;  
END;
/
begin
  DELETE_a(5);
end;
/
select * from a ;
select * from b ;


Chris Saxon
September 18, 2017 - 12:51 pm UTC

Thanks for sharing Fahd.

Next generation auditing

Bengic, January 27, 2020 - 2:09 am UTC

Hi, Check out www.bengic.com, they provide a beautiful UI to see the changes in real time. Simply configure and use. This can be customised to track only specific column type, columns, table and host .. a friendly solution for developers and testers . Hope this helps.

More to Explore

Backup/Recovery

Check out the complete guide to all of the Backup & Recovery techniques in the Oracle Database.