当TRIGGER需要选择并在同一个表中插入行时,变异表问题

Nav*_*vin 4 sql oracle plsql oracle11g

我们有以下要求:

表1:复合主键version, id

------------------------------------
version   id     col1  coll2  active
------------------------------------
 1        123    'A'   'B'     'N'
 2        123    'C'   'D'     'Y'
 1        124    'E'   'F'     'Y'
Run Code Online (Sandbox Code Playgroud)

现在,table1对于给定的任何插入和更新id,应使用以下属性(由触发器派生)创建新行:

  1. Version对于给定id和,应该增加1
  2. 最新的行应该变为活动状态(active列设置为Y)

例如

INSERT INTO table1(id, col1, col2) VALUES (123, 'X', 'Y');

------------------------------------
version   id     col1  coll2  active
------------------------------------
 1        123    'A'   'B'     'N'
 2        123    'C'   'D'     'N'
 3        123    'X'   'Y'     'Y' 
 1        124    'E'   'F'     'Y'
Run Code Online (Sandbox Code Playgroud)

第3行已创建

UPDATE table1 SET col1 = 'F' WHERE id = 124;

------------------------------------
version   id     col1  coll2  active
------------------------------------
 1        123    'A'   'B'     'N'
 2        123    'C'   'D'     'N'
 3        123    'X'   'Y'     'Y' 
 1        124    'E'   'F'     'N'
 2        124    'F'   'F'     'Y'
Run Code Online (Sandbox Code Playgroud)

最后一行已创建

DELETE FROM dbo.table1 WHERE id = 124;

------------------------------------
version   id     col1  coll2  active
------------------------------------
 1        123    'A'   'B'     'N'
 2        123    'C'   'D'     'N'
 3        123    'X'   'Y'     'Y' 
 1        124    'E'   'F'     'N'
 2        124    'F'   'F'     'N'
Run Code Online (Sandbox Code Playgroud)

id 124的所有行都变为非活动状态.

这似乎是建模问题,但我们被要求使用TABLE1和支持触发器来提供此功能.

我们无法根据需要修改表格问题select max(version) ,然后插入到同一个表格中,任何人都可以建议一个解决方法吗?

Ton*_*ews 5

我不喜欢数据库设计,这太可怕了,但是你说你坚持使用它.使用带有INSTEAD OF触发器的视图怎么样?

1)将表重命名为例如TABLE1_BASE

2)创建视图TABLE1作为SELECT*FROM TABLE1_BASE

3)添加一个INSTEAD OF触发器,如下所示:

create trigger table1_io
instead of insert or update or delete on table1
for each row
begin
  if inserting or updating then 
      update table1_base
      set active = 'N'
      where id = :new.id
      and active = 'y';

      insert into table1_base...;
  elsif deleting then
      update table1_base
      set active = 'N'
      where id = :old.id
      and active = 'y';
  end if;
end;
Run Code Online (Sandbox Code Playgroud)

(像这样)