插入到查询中

当查找Oracle的INSERT语法时,我发现你可以插入查询中,例如

insert into (select * from dept) (deptno, dname) values (99, 'new department');

任何人都可以阐明这是什么意思? 我可以通过插入一个查询来实现什么功能,而不能直接插入表中?

更新:到目前为止,它似乎只是一种替代语法,所以我可以写

insert into (select deptno, dname from dept) values (99, 'new department');

代替

insert into dept (deptno, dname) values (99, 'new department');

同样的事情,同样的执行计划。 查询是否返回记录无关紧要。 这个:

insert into (select deptno, dname from dept where 1 = 0) values (99, 'new department');

再次导致相同的执行计划。 所以我们可能会认为,只要我们只从一个表中选择列,那么子查询的样子实际上并不重要。 但不是。 这个:

insert into (select deptno, dname from dept cross join some_table)
values (99, 'new department');

导致“ORA-01779:无法修改映射到非键保存表的列”或“ORA-01732:数据操作操作在此视图上不合法”。

我有这样的印象:Oracle决定允许插入到查询中,因为它们允许插入到视图中,还有什么是子查询,然后是特别视图? 所以,当你可以插入到视图中时,它们当然也可以让你插入到临时视图中,但是当然,没有人会正确地使用这种语法:-)

但也许我错了? 也许这个语法提供了一些我还没有意识到的东西? 如果是这样告诉我:-)


子查询定义了要插入行的表的列。 正如oracle的文档(12c)所说:

指定要插入行的子查询返回的一列或多列的名称。 如果您指定视图或对象视图,则数据库将行插入视图的基表中。

create table test_isq (
    pk integer not null primary key, data_1 varchar2(40), data_2 varchar2(40), data_3 varchar2(40)
);

-- ok
insert into (select pk, data_2, data_3 from test_isq) (pk, data_2) values ( 1, 'Test');
insert into (select pk, data_2, data_3 from test_isq) values ( 2, 'Another', 'Test' );

-- fail
insert into (select data_1 from test_isq) values ( 'This', 'one', 'fails');
insert into (select data_1 from test_isq) (pk, data_1) values ( 42, 'Nope');

drop table test_isq;

插入子查询允许使用WITH CHECK OPTION限制结果。

例如,假设您想要允许除“新部门”之外的任何部门名称。 这个使用不同值的例子工作正常:

SQL> insert into
  2  (select deptno, dname from dept where dname <> 'new department' WITH CHECK OPTION)
  3  values (98, 'old department');

1 row created.

但是,如果插入的值不正确,则会引发错误:

SQL> insert into
  2  (select deptno, dname from dept where dname <> 'new department' WITH CHECK OPTION)
  3  values (99, 'new department');
(select deptno, dname from dept where dname <> 'new department' WITH CHECK OPTION)
                           *
ERROR at line 2:
ORA-01402: view WITH CHECK OPTION where-clause violation

我从来没有见过这种野外使用的功能。 视图有这个选项,所以你应该能够对子查询做同样的事情。 我不确定为什么有人会想要这样做,但对于提供INSERT的SELECT语句的限制很容易。 如果INSERT使用VALUES,则将它转换为SELECT语句是微不足道的。

您必须真正深入语法图才能看到此功能:insert - > single_table_insert - > subquery - > query_block - > table_reference - > query_table_expression - > subquery_restriction_clause。


这是因为INSERT到SELECT语句从一个表中选择数据并将其插入到现有表中。 目标表中的任何现有行都不受影响。

链接地址: http://www.djcxy.com/p/91523.html

上一篇: Insert into a query

下一篇: SMS Service that uses +44 7781 470659