2015-11-12 42 views
4

我有包含標識列的表在Oracle數據庫12C:如何在插入帶有標識列的Oracle表時使用%ROWTYPE?

CREATE TABLE foo (
    id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, 
    bar NUMBER 
) 

現在我要插入到使用PL/SQL表。因爲在實踐中,表中有很多列,我使用%ROWTYPE

DECLARE 
    x foo%ROWTYPE; 
BEGIN 
    x.bar := 3; 
    INSERT INTO foo VALUES x; 
END; 

但是,它給我這個錯誤:

ORA-32795: cannot insert into a generated always identity column
ORA-06512: at line 5

既然是代碼的可讀性和可維護性非常好,我不想停止使用%ROWTYPE。由於我在任何情況下都不想允許任何內容,除了自動生成的ID,我不想解除GENERATED ALWAYS限制。

This文章建議能夠使用%ROWTYPE的唯一方法是切換到GENERATED BY DEFAULT ON NULL。有沒有其他方法可以解決這個問題?

+0

'GENERATED BY DEFAULT ON NULL''有什麼問題? –

+2

@MatthewMcPeak有人可以插入自己的「id」,這不是序列的一部分。我不想這樣做。 – Anders

回答

3

您可以創建一個視圖,插入有:

CREATE OR REPLACE VIEW V_FOO AS 
SELECT BAR -- all columns apart from virtual columns 
FROM foo; 

DECLARE 
    x V_FOO%ROWTYPE; 
BEGIN 
    x.bar := 3; 
    INSERT INTO V_FOO VALUES x; 
END; 
+0

謝謝你的回答。智能解決方法!寧願不需要任何額外的對象,所以我會等待一段時間,然後接受並看看人們有什麼其他的想法。 – Anders

+0

好吧,如果你不喜歡創建視圖,你可以通過'ALL_TAB_COLS'循環,並且使用Package [DBMS_SQL](http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/ d_sql.htm#BABEDAHF)。但是,你將不得不編寫大量的代碼,這絕對是一個矯枉過正的問題。 –

+0

好點的Wernfried,更不用說結果代碼會是低效率了。 –

4

我能想到的,唯一的事情,因爲你在12C是使標識列INVISIBLE,如下面的代碼。

問題是,它使得得到一個%ROWTYPE該id有點困難,但它是可行的。

當然,它也可能會混淆其他使用你的表的人看不到主鍵!

我不認爲我會這樣做,但它您的問題的答案,爲什麼值得。

DROP TABLE t; 

CREATE TABLE t (id number invisible generated always as identity, 
       val varchar2(30)); 

insert into t (val) values ('A');     

DECLARE 

    record_without_id t%rowtype; 
    CURSOR c_with_id IS SELECT t.id, t.* FROM t; 
    record_with_id c_with_id%rowtype; 

BEGIN 
    record_without_id.val := 'C'; 
    INSERT INTO t VALUES record_without_id; 

    -- If you want ID, you must select it explicitly 
    SELECT id, t.* INTO record_with_id FROM t WHERE rownum = 1; 

    DBMS_OUTPUT.PUT_LINE(record_with_id.id || ', ' || record_with_id.val); 
END; 
/

SELECT id, val FROM t;  
+0

我同意這可能會導致更大的問題,而不是解決問題。不過,無論如何,我都很欣賞這個想法。總是很好,讓桌上的所有選項。 – Anders

相關問題