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

And*_*rus 21 sql postgresql database-design plpgsql postgresql-9.2

我试图使用Check中的代码来确定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;
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 29

Postgres 9.5+

IF NOT EXISTSCREATE SEQUENCE在Postgres 9.5中添加了.这是现在的简单解决方案:

CREATE SEQUENCE IF NOT EXISTS myschema.myseq;
Run Code Online (Sandbox Code Playgroud)

但是无论如何都要考虑过时答案的细节......
你知道serial列,对吗?


Postgres 9.4或更高版本

序列的名称与几种类型的对象的名称冲突,而不仅仅是序列.手册:

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

大胆强调我的.
所以你有三种情况:

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

您需要在这两种情况中指定要执行的操作.该DO声明看起来是这样的:

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$;
Run Code Online (Sandbox Code Playgroud)

根据手册中的对象类型(relkind)pg_class:

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

有关:


Joe*_*haw 13

我走了一条不同的路线:抓住异常:

DO
$$
BEGIN
        CREATE SEQUENCE myseq;
EXCEPTION WHEN duplicate_table THEN
        -- do nothing, it's already there
END
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

这样做的一个很好的好处是您不必担心当前的架构是什么.


Eva*_*oky 10

如果您不需要保留可能存在的序列,则可以删除它然后重新创建它:

DROP SEQUENCE IF EXISTS id_seq;
CREATE SEQUENCE id_seq;
Run Code Online (Sandbox Code Playgroud)