在不改变环境的情况下从表中删除列
我正在研究Oracle SQL数据库,数据库相当大。其中一个表格(150个表格中的一个)必须更改,因为它是多余的(它可以通过连接生成)。我被要求从这张表中删除一列,以摆脱冗余。问题是,现在我不得不在任何地方改变代码,在这个表上插入/更新/等(并且不要忘记约束!)。我认为“我可以做一个视图,做正确的连接”,所以它解决了所有选择的问题,但它不适用于插入,因为我正在更新2个表格......有没有办法解决这个问题?在不改变环境的情况下从表中删除列
我的目标是我的重命名原始表original_table
在original_table_smaller
(少了一个列),并创建一个view
(或者类似的视图)被称为original_table
的作用就像原始表。
这可能吗?
由于您的视图将包含实际表格中不存在的一列,因此您需要使用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
INSTEAD OF触发器正是我所期待的。谢谢! – 2013-05-02 08:42:38
可以在视图上插入/更新。 您可能想要检查USER_UPDATABLE_COLUMNS可以插入到视图中的哪些列。
检查与此查询:
select * from user_updatable_columns where table_name = 'VIEW_NAME';
甲骨文使视图都可以更新的两种不同的方式: -
- 的观点是“重点保障”相对于您要更新什么。这意味着基础表的主键在视图中,并且该行在视图中只出现一次。这意味着Oracle可以确切地确定要更新哪个基础表行。或者您可以编写而不是触发器。
据我知道这是不可能做'insert','update'或在视图上删除。只允许“选择”。 – 2013-05-02 08:00:03
是的,这是可能的,但插入/更新/删除的现有代码将失败(您无法在视图上插入/更新/删除行)。 – 2013-05-02 08:00:12
@LinusCaldwell当然你可以制作可更新的视图,例如使用'而不是'触发器。 – 2013-05-02 08:01:45