2015-11-12 43 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

相关问题