【问题标题】:Oracle insert with check option带有检查选项的 Oracle 插入
【发布时间】:2017-04-15 09:47:51
【问题描述】:

这是来自插入语句的Oracle Database 12 documentation

带有检查选项

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

我无法理解最后一句话:

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

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

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

但是当直接放在 FROM 子句之后时,它会产生“ORA-00907:缺少右括号”错误。 IE。如文档所述,将 WITH CHECK OPTION 放在 FROM 子句之后不是有效的 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>

是文档有误还是我遗漏了什么?

【问题讨论】:

  • 也许“不在 WHERE 子句中的子查询中”指的是 where id in (select ... with check option ..)
  • 可能。只是感觉内部选择会被称为子查询,但我真的不知道。
  • 我将内部选择称为“派生表”,而不是子查询
  • 内部 SELECT 是一个子查询,但 ISTM 在 WHERE 子句中使用此类子查询存在限制 - 它没有指定 WITH CHECK OPTION 在它是子查询。 CREATE VIEW 语法表示 WITH CHECK OPTIONWHERE 子句之后。

标签: sql oracle sql-insert


【解决方案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.

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

【讨论】:

    【解决方案2】:

    今天有同样的问题 - 再次阅读参考时,现在它是有道理的: 考虑到我们有:

    INSERT into t1 
        Select c from ( 
            select c2 from t2 where c2=1 with check option
        )
    
    • 在子选择中使用了检查选项(c2 from t2)
    • 参考说:

      在 from 子句(select c from)中使用,而不是在 where 子句中使用 - 这里不存在(但仅在子选择中(子选择)

    【讨论】:

      【解决方案3】:

      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 不能被更改,因为它是用检查选项创建的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-13
        • 2019-06-03
        • 1970-01-01
        • 2015-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多