And*_*ers 6 oracle plsql identity-column rowtype oracle12c
我有一个Oracle 12c数据库,其中包含一个包含标识列的表:
CREATE TABLE foo (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
bar NUMBER
)
Run Code Online (Sandbox Code Playgroud)
现在我想使用PL/SQL插入表中.由于实际上表有很多列,我使用%ROWTYPE:
DECLARE
x foo%ROWTYPE;
BEGIN
x.bar := 3;
INSERT INTO foo VALUES x;
END;
Run Code Online (Sandbox Code Playgroud)
但是,它给了我这个错误:
ORA-32795:无法插入生成的始终标识列
ORA-06512:第5行
由于它非常适合代码可读性和可维护性,我不想停止使用%ROWTYPE.由于我在任何情况下都不想允许除自动生成的ID以外的任何内容,我不想解除GENERATED ALWAYS限制.
该文章建议,只有这样才能够使用%ROWTYPE是切换到GENERATED BY DEFAULT ON NULL.有没有其他方法可以解决这个问题?
我唯一可以想到的是,因为你在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;
Run Code Online (Sandbox Code Playgroud)
您可以创建一个视图并插入其中:
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;
Run Code Online (Sandbox Code Playgroud)