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的文档部分中没有提到这样的内容。或者我只是做错了什么?
答案 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
您无法在以下构造中使用CURRVAL
和NEXTVAL
:
DELETE
,SELECT
或UPDATE
声明中的子查询SELECT
语句与另一个SELECT
语句与UNION,INTERSECT
或MINUS
设置运算符上面的subquery
和SET
操作规则应该回答您的问题。
由于NULL的原因,当pseudocolumn
(例如NEXTVAL)与SET操作或上面提到的任何其他规则一起使用时,输出为NULL,因为Oracle无法通过组合多个选择来提取它们
让我们看看下面的查询,
select rownum from dual
union all
select rownum from dual
结果是
ROWNUM
1
1