首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >始终在串行列中使用下一个序列(不允许用户值)

始终在串行列中使用下一个序列(不允许用户值)
EN

Stack Overflow用户
提问于 2016-06-25 23:13:31
回答 2查看 136关注 0票数 1

在PostgreSQL中,我希望创建一个具有自动增量列的表,其中用户不能指定自定义值。

在Oracle中,有两种方法可以创建自动增量列。

在第一个示例中,如果用户不分隔值,则id列将自动递增。这是postgres中串行的当前实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE identity_test_tab ( 
   id NUMBER GENERATED BY DEFAULT AS DENTITY,
   description VARCHAR2(30) 
);

在下一个示例中,id列是,总是自动递增,用户不能指定任何其他值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE identity_test_tab (
  id          NUMBER ALWAYS AS IDENTITY,
  description VARCHAR2(30)
);

我想知道与postgres中的第二个例子相等的是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-26 08:19:13

这可以通过授予只对特定列插入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;

然后:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)
票数 2
EN

Stack Overflow用户

发布于 2016-06-26 00:27:54

如果要确保总是从序列中提取值,则需要触发器。在Postgres中没有类似于generated always的内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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的任何用户提供的值替换为序列值。如果希望在执行此操作时出现显式错误,请在触发器函数中引发异常:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;

引发异常将中止当前事务,并将迫使应用程序将值插入回滚并正确执行。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38036069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文