Oracle标识列并插入到select中

Kom*_*owy 12 oracle identity-column oracle12c

Oracle 12引入了很好的功能(应该很久以前就已经存在了!) - 标识列.所以这是一个脚本:

CREATE TABLE test (
    a INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    b VARCHAR2(10)
);

-- Ok
INSERT INTO test (b) VALUES ('x');

-- Ok
INSERT INTO test (b)
SELECT 'y' FROM dual;

-- Fails
INSERT INTO test (b)
SELECT 'z' FROM dual UNION ALL SELECT 'zz' FROM DUAL;
Run Code Online (Sandbox Code Playgroud)

前两个插入运行没有问题,提供'a'为1和2的值.但第三个插入失败ORA-01400: cannot insert NULL into ("DEV"."TEST"."A").为什么会这样?一个bug?关于标识列限制的文档部分中没有提到这样的内容.或者我只是做错了什么?

Mah*_*kar 9

我相信以下查询有效,我还没有测试过!

INSERT INTO Test (b)
SELECT * FROM
(
   SELECT 'z' FROM dual
   UNION ALL
   SELECT 'zz' FROM dual
);
Run Code Online (Sandbox Code Playgroud)

不确定,如果它对你有所帮助.

对于,GENERATED ALWAYS AS IDENTITYOracle内部仅使用序列.一般序列的选项也适用于此.

NEXTVAL用于获取下一个可用序列,显然它是一个伪列.

以下是来自Oracle

您不能在以下构造中使用CURRVALNEXTVAL:

  • 在一个子查询DELETE,SELECTUPDATE声明
  • 查询视图或物化视图
  • 带有DISTINCT运算符的SELECT语句
  • 带有GROUP BY子句或ORDER BY子句的SELECT语句
  • 一个SELECT是结合另一份声明SELECT语句与UNION,INTERSECTMINUS设置操作
  • SELECT语句的WHERE子句
  • CREATE TABLE或ALTER TABLE语句中列的DEFAULT值
  • CHECK约束的条件

subquerySET上述操作规则应该回答你的问题.

并且由于NULL的原因,当pseudocolumn(例如NEXTVAL)与SET操作或上面提到的任何其他规则一起使用时,输出为NULL,因为Oracle无法通过组合多个选择来提取它们.

让我们看看下面的查询,

select rownum from dual
union all 
select rownum from dual
Run Code Online (Sandbox Code Playgroud)

结果是

ROWNUM
1
1
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的详细解释!事实上,当明确地使用序列时,`INSERT INTO test(a)SELECT seq.nextval FROM dual UNION ALL SELECT seq.nextval FROM dual;`带来更多解释`"ORA-02287:这里不允许的序列号"`.似乎身份列必须以某种方式绕过此检查,但序列无论如何都不起作用,只提供NULL作为值 - 因此不寻常的错误消息. (2认同)