在PostgreSQL中,我希望创建一个具有自动增量列的表,其中用户不能指定自定义值。
在Oracle中,有两种方法可以创建自动增量列。
在第一个示例中,如果用户不分隔值,则id列将自动递增。这是postgres中串行的当前实现。
CREATE TABLE identity_test_tab (
id NUMBER GENERATED BY DEFAULT AS DENTITY,
description VARCHAR2(30)
);
在下一个示例中,id列是,总是自动递增,用户不能指定任何其他值。
CREATE TABLE identity_test_tab (
id NUMBER ALWAYS AS IDENTITY,
description VARCHAR2(30)
);
我想知道与postgres中的第二个例子相等的是什么?
发布于 2016-06-26 08:19:13
这可以通过授予只对特定列插入:
drop table if exists t;
create table t(i serial, x text, y int);
grant insert (x,y) on table t to abelisto;
grant usage on sequence t_i_seq to abelisto;
grant select on table t to abelisto;
然后:
postgres=# insert into t(i,x,y) values(10,'x',1);
ERROR: permission denied for relation t
postgres=# insert into t(i,x,y) values(default,'x',1);
ERROR: permission denied for relation t
postgres=# insert into t(x,y) values('x',1);
INSERT 0 1
postgres=# select * from t;
i | x | y
---+---+---
1 | x | 1
(1 row)
发布于 2016-06-26 00:27:54
如果要确保总是从序列中提取值,则需要触发器。在Postgres中没有类似于generated always
的内容:
create table foo (id integer not null primary key);
create sequence foo_id_seq;
alter sequence foo_id_seq owned by foo.id; -- this is essentially what `serial` does in the background
create function generate_foo_id()
returns trigger
as
$$
begin
new.id := nextval('foo_id_seq');
return new;
end;
$$
language plpgsql;
create trigger foo_id_trigger
before insert on foo
for each row execute procedure generate_foo_id();
上面的内容将悄悄地将foo.id
的任何用户提供的值替换为序列值。如果希望在执行此操作时出现显式错误,请在触发器函数中引发异常:
create function generate_foo_id()
returns trigger
as
$$
begin
if new.id is not null then
raise 'No manual value for id allowed';
end if;
new.id := nextval('foo_id_seq');
return new;
end;
$$
language plpgsql;
引发异常将中止当前事务,并将迫使应用程序将值插入回滚并正确执行。
https://stackoverflow.com/questions/38036069
复制相似问题