意见的改变

时间:2014-06-25 03:55:19

标签: database oracle11g views

以下是我创建的示例表的代码:

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。

1 个答案:

答案 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重新创建视图 - 您不会像丢弃表一样丢失数据。