我尝试使用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;
答案 0 :(得分:25)
IF NOT EXISTS
was added to CREATE SEQUENCE
。这就是现在的简单解决方案:
CREATE SEQUENCE IF NOT EXISTS myschema.myseq;
但是无论如何都要考虑过时答案的细节......
您知道serial
列,对吗?
序列的名称与几种类型的对象的名称冲突,而不仅仅是序列。 The manual:
序列名称必须与任何其他名称不同 同一模式中的序列,表,索引,视图或外表。
大胆强调我的 所以你有三种情况:
您需要在上述任何一种情况下指定要执行的操作。 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 =普通表
i =指数
S =序列
v =观看
m =物化视图
c =复合型
t = TOAST表
f =外国表
相关:
答案 1 :(得分:13)
我走了另一条路线:抓住异常:
DO
$$
BEGIN
CREATE SEQUENCE myseq;
EXCEPTION WHEN duplicate_table THEN
-- do nothing, it's already there
END
$$ LANGUAGE plpgsql;
这样做的一个好处是,您无需担心当前的架构是什么。
答案 2 :(得分:10)
如果您不需要保留可能存在的序列,您可以删除它然后重新创建它:
largestString
答案 3 :(得分:2)
Postgres没有CREATE SEQUENCE IF NOT EXISTS
,如果您只是删除序列,如果表使用序列具有默认值,则可能会出错:
错误:无法删除序列(sequence_name),因为其他对象依赖于它SQL状态:2BP01
对我来说,这个可以提供帮助:
ALTER TABLE <tablename> ALTER COLUMN id DROP DEFAULT;
DROP SEQUENCE IF EXISTS <sequence_name>;
CREATE sequence <sequence_name>;
答案 4 :(得分:0)
可以从information_schema.sequences
(reference)
尝试这样的事情(未经测试):
...
IF not EXISTS (SELECT * FROM information_schema.sequences
WHERE sequence_schema = 'firma1' AND sequence_name = 'myseq') THEN
...
答案 5 :(得分:0)
我有一个函数可以随时清理我的数据库应用程序中的所有表。它是动态构建的,但实质是它会删除每个表中的所有数据并重置序列。 这是重置其中一个表序列的代码:
perform relname from pg_statio_all_sequences where relname = 'privileges_id_seq';
if found then
select setval ('privileges_id_seq',1, false) into i_result;
end if;
希望这有帮助,
Loek
我正在使用postgres 8.4,我看到你使用9.2。可以在存储信息的地方有所作为。