Oracle标识列并插入到select中

时间:2014-01-25 20:20:40

标签: 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;

前两个插页在没有问题的情况下运行,为' a' 1和2.但第三个失败了ORA-01400: cannot insert NULL into ("DEV"."TEST"."A")。为什么会这样?一个bug?关于identity column restrictions的文档部分中没有提到这样的内容。或者我只是做错了什么?

1 个答案:

答案 0 :(得分:9)

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

INSERT INTO Test (b)
SELECT * FROM
(
   SELECT 'z' FROM dual
   UNION ALL
   SELECT 'zz' FROM dual
);

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

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

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

以下内容来自Oracle

您无法在以下构造中使用CURRVALNEXTVAL

  • DELETESELECTUPDATE声明中的子查询
  • 查看视图或物化视图
  • 带有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

结果是

ROWNUM
1
1