我尝试使用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;
IF NOT EXISTS
was added to CREATE SEQUENCE
在Postgres 9.5中。这就是现在的简单解决方案:
IF NOT EXISTS
但是无论如何都要考虑过时答案的细节...而且您知道CREATE SEQUENCE
或CREATE SEQUENCE IF NOT EXISTS myschema.myseq;
列,对吗?
serial
序列与其他几个类似表的对象共享名称空间。 IDENTITY
序列名称必须与任何其他名称不同 序列,表,索引,视图或外部表在同一模式中。
大胆强调我的。因此有三种情况:
指定两种情况下的处理方法。 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$;
我走了一条不同的路线:只是捕捉到异常:
Object types (relkind
) inpg_class
according to the manual
一个很好的好处是,您不必担心当前的架构是什么。
如果不需要保留潜在的现有序列,则可以将其删除然后重新创建:
relkind
Postgres没有pg_class
,如果您只是删除序列而表具有使用序列的默认值,则可能会出错:
错误:无法删除序列(sequence_name),因为其他对象都依赖它SQL状态:2BP01
对我来说,这可以帮助您:
How to check if a table exists in a given schema
关于序列的信息可以从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
我具有随时清除数据库应用程序中所有表的功能。它是动态构建的,但本质是它从每个表中删除了所有数据并重置了序列。这是重置表之一顺序的代码:
ALTER TABLE <tablename> ALTER COLUMN id DROP DEFAULT;
DROP SEQUENCE IF EXISTS <sequence_name>;
CREATE sequence <sequence_name>;
希望这会有所帮助,
Loek
我使用的是Postgres 8.4,我看到您使用的是9.2。可能会影响信息的存储位置。