我尝试使用来自 Check if sequence exists in Postgres (plpgsql) 的代码.
如果序列不存在则创建序列。运行此代码两次会导致异常:
sequence ... already exists.
如何只在不存在的情况下创建序列?
如果序列不存在,则不应写入任何消息,也不应发生任何错误,因此我无法在该问题的其他答案中使用存储过程,因为如果序列存在,它每次都会将消息写入日志文件。
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;
最佳答案
Postgres 9.5 或更高版本
IF NOT EXISTS
was added to CREATE SEQUENCE
在 Postgres 9.5 中。这是现在的简单解决方案:
CREATE SEQUENCE IF NOT EXISTS myschema.myseq;
但无论如何都要考虑过时答案的细节......
您知道 serial
或 IDENTITY
列,对吗?
Postgres 9.4 或更早版本
序列与其他几个类似表的对象共享命名空间。 The manual:
The sequence name must be distinct from the name of any other sequence, table, index, view, or foreign table in the same schema.
大胆强调我的。所以分为三种情况:
- 名称不存在。 -> 创建序列。
- 存在同名序列。 ->什么都不做?有输出吗?有记录吗?
- 存在其他具有相同名称的冲突对象。 -> 做点什么?有输出吗?有记录吗?
指定在任何一种情况下要做什么。 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$;
Object types (relkind
) in pg_class
according to the manual :
r = ordinary table
i = index
S = sequence
v = view
m = materialized view
c = composite type
t = TOAST table
f = foreign table
相关:
关于sql - 如果不存在如何创建序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13752885/