1

我有一个表格参与者,其结构如下所示:

Pid    number        
name   varchar2(20)    
version  number

每当我在表中插入任何记录时participants,版本 =1都会被填充。

例如,如果我插入 pid=1 ,name='Gaurav' 然后记录version =1get 填充 in participants table

现在我issueupdateparticipants桌子上,

  1. 假设我正在为参与者表中的 pid=1 更新 name ='Niharika' ,那么需要在同一张表上创建一个 pid=1 、name='Niharika' 和版本 =2 的新记录。
  2. 我再次为参与者表中的 pid='1' 更新 name='Rohan' ,需要创建 pid=1 、name='Rohan' 和 version=3 的新记录。

我怎样才能做到这一点,显然我需要为将要更新的 pid 获取 max(version)+1 。

我可以使用视图来实现这一点,并使用而不是触发器插入视图,但我对我的解决方案不满意。

我还创建了复合触发器,即使这对我不起作用,因为在触发器内部我需要对该表使用插入语句,这会给我递归错误

4

2 回答 2

2

你真的应该有两张桌子。使用您描述为“日志记录”表的结构制作一个。它将保留所有记录的历史记录。有另一个被认为是“当前”的表,它是相同的但没有version列。然后,当在“当前”表的记录上发生插入/更新时,有一种机制(例如触发SELECT FOR UPDATE)日志表中的 max(version),添加一个,然后插入到日志表中。这样,您就不会遇到变异表错误或任何类似的奇怪问题。这种方式有一些序列化,但它最接近你想要做的事情。

于 2012-07-18T22:51:47.563 回答
-1

通常不推荐,但无论如何您都可以在没有其他额外日志记录表的情况下执行此操作-

CREATE or REPLACE
TRIGGER part_upd
 AFTER UPDATE of name
 ON participants
 FOR EACH ROW
DECLARE
  retval BOOLEAN;
BEGIN

   retval := insert_row(:old.pid,:new.name);

END part_upd;

功能-

CREATE or REPLACE 
FUNCTION insert_row (pid1 number, name1 varchar2)
RETURN boolean
IS
    PRAGMA autonomous_transaction;
BEGIN
     INSERT INTO participants
     SELECT pid1, name1, max(vers)+1
       FROM participants
      WHERE pid = pid1;         

     COMMIT; 

     RETURN true;
END;

您必须通过添加日志记录和异常处理来正确调整触发器和函数。阅读有关自主事务的更多信息。

于 2012-07-19T02:33:47.723 回答