以下是我创建的示例表的代码:
SQL> create table a (a1 number(2), a2 number(2) not null);
Table created.
现在假设我在此表上创建了一个视图:
SQL> create view aview as select a1 from a;
View created.
我需要3个问题的意见:a。有没有办法在此视图中插入值。湾如果我使用drop view语句删除视图。有没有办法像使用闪回的表一样恢复? C。如果我想在这个视图中添加像主键这样的constarint,那就不允许我了。我想知道为什么?这就是我的尝试:
SQL> alter view aview add primary key(a1);
alter view aview add primary key(a1)
*
ERROR at line 1:
ORA-00922: missing or invalid option
SQL> alter view aview add primary key a1;
alter view aview add primary key a1
*
ERROR at line 1:
ORA-00906: missing left parenthesis
我正在使用Oracle 11g。
答案 0 :(得分:1)
您可以向视图添加约束,但the documentation says:
查看约束
Oracle数据库不强制实施视图约束。但是,您可以通过对基表的约束来强制实施视图约束。您只能在视图上指定唯一,主键和外键约束,并且仅在
DISABLE NOVALIDATE
模式下支持它们。您无法在对象列的属性上定义视图约束。
所以要创建你需要的主键:
SQL> alter view aview add primary key(a1) disable novalidate;
view AVIEW altered.
或使用命名约束:
alter view aview add constraint aview_pk primary key(a1) disable novalidate;
但由于没有强制执行,您仍然可以在视图中包含重复值,并且可以插入新的重复值。
您无法直接作为基表插入到视图中作为a2
上的非空约束,您没有提供。你会得到一个ORA-01400。如果您有一个默认值,可以用于a2
,那么您可以将其添加到表定义中:
create table a (a1 number(2), a2 number(2) default 0 not null);
create view aview as select a1 from a;
alter view aview add constraint aview_pk primary key(a1) disable novalidate;
insert into aview (a1) values (42);
select * from a;
A1 A2
---------- ----------
42 0
或者您可以创建一个替代触发器,如果视图更复杂(例如,使用连接),这就是您需要执行的操作:
create table a (a1 number(2), a2 number(2) not null);
create view aview as select a1 from a;
alter view aview add constraint aview_pk primary key(a1) disable novalidate;
create trigger aview_trig
instead of insert on aview
begin
insert into a values (:new.a1, 0);
end;
/
insert into aview (a1) values (42);
select * from a;
A1 A2
---------- ----------
42 0
但即使您在视图中使用主键,也可以这样做:
insert into aview (a1) values (42);
select * from a;
A1 A2
---------- ----------
42 0
42 0
如果您希望表格不允许重复,则需要主键或唯一键。如果您希望表具有重复项但视图不确定它们,请将其区分开来:
create view aview as select distinct a1 from a;
...但是默认值不足以允许您插入视图(您将获得ORA-01732)并且您必须使用instead of
触发器。
如果放下视图,它不会保留在回收站中:
drop view aview;
drop table a;
select type, original_name, object_name, operation from user_recyclebin;
TYPE ORIGINAL_NAME OBJECT_NAME OPERATION
----- ------------------ ------------------------------ ---------
TABLE A BIN$/KaYRJ66eC3gQwEAAH/46Q==$0 DROP
只保留包含数据的对象。由于视图没有数据,它只是一个预定义的查询,没有什么可以真正存储,并且它很简单,可以从其DDL重新创建视图 - 您不会像丢弃表一样丢失数据。