如果不存在,如何创建序列

问题描述 投票:25回答:6

我尝试使用Check if sequence exists in Postgres (plpgsql)中的代码。

如果不存在则创建序列。两次运行此代码会导致异常:

序列...已经存在。

仅在不存在时如何创建序列?

如果序列不存在,则不应写入任何消息,也不应发生错误,因此我无法在该问题的其他答案中使用存储过程,因为如果序列存在,则每次都会将消息写入日志文件。

do $$
begin

SET search_path = '';
IF not EXISTS (SELECT * FROM pg_class
             WHERE relkind = 'S'
               AND oid::regclass::text = 'firma1.' || quote_ident('myseq'))
  THEN

SET search_path = firma1,public;

create sequence myseq;

END IF;

SET search_path = firma1,public;

end$$;

select nextval('myseq')::int as nr;
sql postgresql database-design plpgsql postgresql-9.2
6个回答
36
投票

Postgres 9.5或更高版本

IF NOT EXISTS was added to CREATE SEQUENCE在Postgres 9.5中。这就是现在的简单解决方案:

IF NOT EXISTS

但是无论如何都要考虑过时答案的细节...而且您知道CREATE SEQUENCECREATE SEQUENCE IF NOT EXISTS myschema.myseq; 列,对吗?

  • serial

Postgres 9.4或更高版本

序列与其他几个类似表的对象共享名称空间。 IDENTITY

序列名称必须与任何其他名称不同 序列,表,索引,视图或外部表在同一模式中。

大胆强调我的。因此有三种情况:

  1. 名称不存在。 ->创建序列。
  2. 存在具有相同名称的序列。 ->什么都不做?有输出吗?是否有日志记录?
  3. 存在其他具有相同名称的冲突对象。 ->做点什么?有输出吗?是否有日志记录?

指定两种情况下的处理方法。 Auto increment table column语句可能如下所示:

The manual:

DO

r =普通表 i =索引 S =序列 v =视图 m =物化视图 c =复合类型 t = TOAST表 f =外国表

相关:

  • DO $do$ DECLARE _kind "char"; BEGIN SELECT relkind FROM pg_class WHERE oid = 'myschema.myseq'::regclass -- sequence name, optionally schema-qualified INTO _kind; IF NOT FOUND THEN -- name is free CREATE SEQUENCE myschema.myseq; ELSIF _kind = 'S' THEN -- sequence exists -- do nothing? ELSE -- object name exists for different kind -- do something! END IF; END $do$;

13
投票

我走了一条不同的路线:只是捕捉到异常:

Object types (relkind) in pg_class according to the manual

一个很好的好处是,您不必担心当前的架构是什么。


10
投票

如果不需要保留潜在的现有序列,则可以将其删除然后重新创建:

relkind

2
投票

Postgres没有pg_class,如果您只是删除序列而表具有使用序列的默认值,则可能会出错:

错误:无法删除序列(sequence_name),因为其他对象都依赖它SQL状态:2BP01

对我来说,这可以帮助您:

How to check if a table exists in a given schema

0
投票

关于序列的信息可以从DO $$ BEGIN CREATE SEQUENCE myseq; EXCEPTION WHEN duplicate_table THEN -- do nothing, it's already there END $$ LANGUAGE plpgsql; DROP SEQUENCE IF EXISTS id_seq; CREATE SEQUENCE id_seq; )中检索

尝试这样(未经测试):

CREATE SEQUENCE IF NOT EXISTS

0
投票

我具有随时清除数据库应用程序中所有表的功能。它是动态构建的,但本质是它从每个表中删除了所有数据并重置了序列。这是重置表之一顺序的代码:

ALTER TABLE <tablename> ALTER COLUMN id DROP DEFAULT;
DROP SEQUENCE IF EXISTS <sequence_name>;
CREATE sequence <sequence_name>;

希望这会有所帮助,

Loek

我使用的是Postgres 8.4,我看到您使用的是9.2。可能会影响信息的存储位置。

© www.soinside.com 2019 - 2024. All rights reserved.