如果您要插入固定值 val1、val2 等,它们将为您表中已存在的每一行插入一次(因为 into 和 from 都引用 application )。您没有插入与现有主键冲突的值,而是多次插入相同的 new 主键,这会产生相同的错误。
如果该表为空,则不会插入任何行;如果它有一行,您将插入一行(如果您没有手动复制密钥,可能是正确的);否则你会自动创建重复项。如果没有导致异常的主键,每次运行时,表中的行数都会增加一倍。
您可以在带有主键的虚拟表上尝试它,以查看实际插入的内容:
create table t42(col1 number, col2 varchar2(10));
insert into t42 values (1, 'A');
insert into t42 values (2, 'B');
insert into t42 values (3, 'C');
insert all
into t42 (col1, col2) values (4, 'D')
into t42 (col1, col2) values (5, 'E')
select * from t42;
6 rows inserted.
select * from t42;
COL1 COL2
---------- ----------
1 A
2 B
3 C
4 D
4 D
4 D
5 E
5 E
5 E
9 rows selected
...所以您可以看到每个into 子句为预先存在于表格中的每一行创建了一个新行。显然,如果 col1 上有 PK,那么您将插入新值的副本。
我认为您唯一想引用同一个表的情况是,如果您要基于其他行创建行,例如(非常做作):
insert all
into application (col1, col2, ...)
values (col1 + 100, col2 || ' adjusted', ...)
select col1, col2 from application;
如果您想输入固定值,您可以从 dual 中进行选择,这将为每个提供的值集提供一行:
insert all
into application (col1, col2, ...)
values (val1, val2, ...)
select * from dual;
从上面重复 demp:
create table t42(col1 number, col2 varchar2(10));
insert into t42 values (1, 'A');
insert into t42 values (2, 'B');
insert into t42 values (3, 'C');
insert all
into t42 (col1, col2) values (4, 'D')
into t42 (col1, col2) values (5, 'E')
select * from dual;
2 rows inserted.
select * from t42;
COL1 COL2
---------- ----------
1 A
2 B
3 C
4 D
5 E
5 rows selected
当然,除非您有多个 into 子句,否则使用 insert all 语法并没有多大意义,即使这样单独的 insert 语句可能会更清晰。