15

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"). 为什么会这样?一个错误?关于身份列限制的文档部分没有提到类似的内容。还是我只是做错了什么?

4

1 回答 1

12

I believe the below query works, i havent tested!

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

Not sure, if it helps you any way.

For, GENERATED ALWAYS AS IDENTITY Oracle internally uses a Sequence only. And the options on general Sequence applies on this as well.

NEXTVAL is used to fetch the next available sequence, and obviously it is a pseudocolumn.

The below is from Oracle

You cannot use CURRVAL and NEXTVAL in the following constructs:

  • A subquery in a DELETE, SELECT, or UPDATE statement
  • A query of a view or of a materialized view
  • A SELECT statement with the DISTINCT operator
  • A SELECT statement with a GROUP BY clause or ORDER BY clause
  • A SELECT statement that is combined with another SELECT statement with the UNION, INTERSECT, or MINUS set operator
  • The WHERE clause of a SELECT statement
  • DEFAULT value of a column in a CREATE TABLE or ALTER TABLE statement
  • The condition of a CHECK constraint

The subquery and SET operations rule above should answer your Question.

And for the reason for NULL, when pseudocolumn(eg. NEXTVAL) is used with a SET operation or any other rules mentioned above, the output is NULL, as Oracle couldnt extract them in effect with combining multiple selects.

Let us see the below query,

select rownum from dual
union all 
select rownum from dual

the result is

ROWNUM
1
1
于 2014-01-26T07:19:48.227 回答