带有check选项的Oracle插入

时间:2017-04-15 09:47:51

标签: sql oracle sql-insert

这是来自Oracle Database 12 documentation的insert语句:

  

WITH CHECK OPTION

     

指定WITH CHECK OPTION以指示Oracle数据库禁止   对表或视图的任何更改将产生不是的行   包含在子查询中。在DML的子查询中使用时   声明,您可以在FROM中的子查询中指定此子句   子句但不在WHERE子句中的子查询中。

我无法理解最后一句话:

  

在DML语句的子查询中使用时,可以指定它   FROM子句中子查询中的子句但不在子查询中   WHERE子句。

似乎暗示WITH CHECK OPTION应该直接在FROM子句之后,当插入有一个子查询时。但它不起作用。恰恰相反。

当WITH CHECK OPTION放在WHERE子句之后它正常工作并产生预期的ORA-01402错误。

但是当直接放在FROM子句之后它会产生一个" ORA-00907:缺少右括号"而是错误。即如文档所述,在FROM子句之后放置WITH CHECK OPTION是不是有效的SQL。

SQL> create table t1
  2  (
  3    col1 number
  4  );

Table created.

SQL> insert into
  2  (
  3    select * from t1
  4    where col1 = 1
  5    with check option
  6  )
  7  values (2);
  select * from t1
                *
ERROR at line 3:
ORA-01402: view WITH CHECK OPTION where-clause violation


SQL> insert into
  2  (
  3    select * from t1
  4    with check option
  5    where col1 = 1
  6  )
  7  values (2);
  where col1 = 1
  *
ERROR at line 5:
ORA-00907: missing right parenthesis


SQL>

文档是错误的还是我错过了什么?

3 个答案:

答案 0 :(得分:1)

我认为“WITH CHECK OPTION”是为VIEWS设计的,但可以在像VIEW一样的INSERT子查询中使用。

继续您的示例:

SQL> create table t1
  2  (
  3    col1 number
  4  );

Table created.

SQL> create table t2
  2  (
  3    col1 number
  4  );

Table created.

SQL> INSERT INTO t2 VALUES (1);

1 row inserted.

SQL> INSERT INTO t1
2 SELECT col1 
3 FROM ( SELECT col1 FROM t2 WHERE col1 = 1 WITH CHECK OPTION );

1 row inserted.

我认为这是一个伪装成视图的子查询。

答案 1 :(得分:1)

今天遇到同样的问题 - 再次阅读裁判时,现在有道理了: 认为我们有:

INSERT into t1 
    Select c from ( 
        select c2 from t2 where c2=1 with check option
    )
  • 检查选项用于子选择(来自t2的c2)
  • ref说:

      

    使用from子句(select c from)而不是where子句 - 这里不存在(但只在subselect(subselect)中

答案 2 :(得分:0)

WITH CHECK OPTION主要用于视图。 例如,在这里有两个视图:

create view view_1 as select * from table_1 where table1_col1; 

-在这里view_1可以通过插入或更新行来更改

create view view_2 as select * from table_2 where table2_col1 with check option;

-此处的view_2由于使用check选项创建,因此无法更改。