【问题标题】:Inserting row values into another table's column将行值插入另一个表的列
【发布时间】:2012-10-12 16:50:11
【问题描述】:

我正在尝试为我的项目实现撤消日志记录功能。

当用户使用 DELETE_ROW 过程从表中删除一行时,我会从该行中选择所有值并将其插入到我的 row_history 表中,方法是使用 LOG_DELETED_ROW 将行值序列化为 xml strong> 过程,然后我从其原始表中删除行。

使用 Oracle 的内置函数进行序列化很容易,但我找不到反序列化行数据并将其插入回自己的表的方法。

有没有办法将删除的行存储到另一个表中并在需要时恢复它?

删除程序:

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;

记录过程:

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;

行历史记录表:

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

【问题讨论】:

  • 为什么不能使用触发器?删除触发器以记录被删除的行。您的恢复标准是什么(从日志表)?
  • 有或没有触发器,我的问题是如何将行的值插入另一个表?并且当需要时,我想从日志表中获取该行并将其插入到它的原始表中。我正在尝试找到一种方法来序列化/反序列化一行。
  • 为什么将xml存储为clob?
  • 我将它存储为 xml,这样我就可以取回那个 clob,反序列化并插入回自己的表中。但这是我最坏的情况,因为我不想搞乱序列化/反序列化的东西。

标签: sql oracle plsql oracle10g


【解决方案1】:

DBMS_XMLSAVE 似乎是你需要的东西。这里有一个程序可以做你需要做的事情。

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;
 /

【讨论】:

    【解决方案2】:

    我相信你可以在这里使用DBMS_SQL 包 - 它可以让你在知道表名和列的情况下重建插入语句。

    另一种更复杂的方法是实例化LCR$_ROW_RECORD 对象,然后运行其EXECUTE 成员——它将执行实际插入。

    【讨论】:

      猜你喜欢
      • 2012-06-23
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 2015-01-18
      • 1970-01-01
      相关资源
      最近更新 更多