2014-01-25 88 views
12

Oracle 12引入了很好的功能(應該早就有btw了!) - 標識列。所以這裏有一個腳本:Oracle標識列和插入選擇

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; 

一兩個插件運行,而不爲1和2的「A」提供價值問題,但是第三個失敗,ORA-01400: cannot insert NULL into ("DEV"."TEST"."A")。爲什麼發生這種情況?一個錯誤?在關於identity column restrictions的文檔部分中未提及此類內容。或者我只是做錯了什麼?

回答

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

  • DELETESELECT,或UPDATE語句中的子查詢
  • 視圖的查詢或物化視圖
  • 帶DISTINCT運算符的SELECT語句
  • SELECT語句與GROUP BY子句或ORDER BY子句
  • SELECT語句與另一個SELECT語句與UNION,INTERSECT,或MINUS集合運算符組合
  • 的WHERE SELECT語句的子句
  • 在CREATE TABLE或ALTER TABLE語句
  • CHECK約束的條件

subquery和列的默認值上面的操作規則應該回答你的問題。

由於NULL的原因,當pseudocolumn(例如NEXTVAL)與SET操作或上述任何其他規則一起使用時,輸出爲NULL,因爲Oracle無法通過組合多個選擇來提取它們。

讓我們來看看下面的查詢,

select rownum from dual 
union all 
select rownum from dual 

結果是

ROWNUM 
1 
1 
+0

+1我只是測試它,它工作得很好。 –

+2

感謝您的詳細解釋!事實上,當明確使用sequence時,'INSERT INTO test(a)SELECT seq.nextval FROM dual UNION ALL SELECT seq.nextval FROM dual;'帶來更多解釋性'「ORA-02287:此處不允許的序列號」。看起來,身份列必須以某種方式繞過此檢查,但序列無論如何都不起作用,僅提供NULL作爲值 - 因此是不尋常的錯誤消息。 –

+0

我沒有足夠的代表編輯,但最後一個項目符號應該是3個單獨的項目符號。很難現在閱讀。 –