从表中删除列而不更改环境

时间:2013-05-02 07:55:56

标签: sql oracle

我正在研究Oracle SQL数据库,这是一个相当大的数据库。其中一个(在150个表中)必须更改此表,因为它是冗余的(可以通过连接生成)。我被要求从该表中删除一列,以消除冗余。问题是现在我必须在有人在这个表上进行插入/更新/等的地方改变代码(并且不要忘记约束!)。我认为“我可以创建一个正确连接的视图”,所以它解决了所有选择的问题,但它不适用于插入,因为我正在更新2个表...有没有办法解决这个问题?

我的目标是在original_table中重命名原始表original_table_smaller(少一列)并创建名为view的{​​{1}}(或类似视图)像原始表一样工作。

这可能吗?

2 个答案:

答案 0 :(得分:3)

由于您的视图将包含实际表中不存在的一列,因此您需要使用instead of触发器来使视图更新。

这样的事情:

create table smaller_table 
(
   id integer not null primary key, 
   some_column varchar(20)
);

create view real_table 
as 
select id,
       some_column,
       null as old_column
from smaller_table;

现在您的旧代码将运行如下:

insert into real_table 
  (id, some_column, old_column)
values
  (1, 'foo', 'bar');

导致:

  

ORA-01733:此处不允许使用虚拟列

要解决此问题,您需要INSTEAD OF触发器:

create or replace trigger comp_trigger 
   instead of insert on smaller_table
begin
  insert into old_table 
    (id, some_column)
  values
    (:new.id, :new.some_column);
end;
/

现在将忽略“old_column”的值。您还需要类似的更新内容。

如果您的视图包含联接,那么您也可以在触发器中处理该情况。只需根据数据更新/插入两个不同的表

有关详细信息和示例,请参阅手册
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#i1006376

答案 1 :(得分:2)

可以在视图上插入/更新。 您可能希望使用USER_UPDATABLE_COLUMNS检查可以插入视图的列。

检查此查询:

select * from user_updatable_columns where table_name = 'VIEW_NAME';

Oracle有两种不同的方法可以更新视图: -

  1. 对于您要更新的内容,视图是“密钥保留”。这意味着基础表的主键位于视图中,并且该行仅在视图中出现一次。这意味着Oracle可以确切地确定要更新的基础表行OR
  2. 你写了一个而不是触发器。