Ahmet Kakıcı
Ahmet Kakıcı

Reputation: 6404

Inserting row values into another table's column

I'm trying to implement an undo and logging feature for my project.

When a user deletes a row from a table with the DELETE_ROW procedure i select all values from that row and insert it into my row_history table by serializing row values as xml with LOG_DELETED_ROW procedure, then i delete row from its original table.

Serializing with built-in functions of Oracle was easy but i couldn't find a way to deserialize the rowdata and insert it back to own table.

Is there any way to store that deleted row into another table and restore it when needed?

Delete Procedure:

create or replace procedure DELETE_ROW(tableName varchar2, userId varchar2, columnName varchar2, columnValue number) is
begin
  log_deleted_row(tableName, userId, columnName, columnValue);
  execute immediate 'delete from ' || tableName || ' where ' || columnName || ' = ' || columnValue;
end DELETE_ROW;

Logging Procedure:

create or replace procedure LOG_DELETED_ROW(tableName varchar2, userId varchar2, columnName varchar2, columnValue number) is
tableId number;
begin
  SELECT ID into tableId FROM TABLES WHERE NAME = tableName;

execute immediate
  'INSERT INTO ROW_HISTORY(TABLE_ID,ROW_ID,ROW_DATA)
   SELECT 
   '|| tableId ||', 
   '|| columnValue ||',
   to_clob(
       DBMS_XMLGEN.getxmltype(
           ''SELECT * FROM ' || tableName || ' where ' || columnName || ' = ' || columnValue || '''
       ) 
   )FROM DUAL';

end LOG_DELETED_ROW;

Row History Table:

create table ROW_HISTORY
(
  ID       NUMBER not null,
  TABLE_ID NUMBER not null,
  ROW_ID   NUMBER not null,
  ROW_DATA CLOB not null
)

Upvotes: 1

Views: 583

Answers (2)

BulentB
BulentB

Reputation: 316

DBMS_XMLSAVE seems to be the thing you need.Here is a procedure which should do what you need to do.

CREATE OR REPLACE PROCEDURE insert_xml_data(p_table IN VARCHAR2, xml_data IN CLOB) IS
   t_context    DBMS_XMLSAVE.CTXTYPE;
   t_rows    NUMBER;
 BEGIN
   t_context := DBMS_XMLSAVE.NEWCONTEXT(p_table); 
   t_rows := DBMS_XMLSAVE.INSERTXML(t_context,xml_data); 
   DBMS_XMLSAVE.CLOSECONTEXT(t_context); 
 END;
 /

Upvotes: 2

Kirill Leontev
Kirill Leontev

Reputation: 10931

I believe you could use DBMS_SQL package here - it will allow you to reconstruct insert statement knowing table name and columns.

Another, more complicated, way would be to insantiate LCR$_ROW_RECORD object and then run its EXECUTE member - it will perform actual insert.

Upvotes: 0

Related Questions