这与使用此代码解决的列创建类似的问题:
https://stackoverflow.com/a/12603892/368511
>索引名称在单个数据库架构中是唯一的.
>索引名称不能与同一模式中的任何其他索引,(外部)表,(物化)视图,序列或用户定义的复合类型相同.
>同一模式中的两个表不能具有相同名称的索引. (逻辑上讲.)
CREATE INDEX ON tbl1 (col1)
是(几乎)相同
CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
除了Postgres将避免命名冲突并自动选择下一个免费名称:
tbl1_col1_idx tbl1_col1_idx2 tbl1_col1_idx3 ...
就试一试吧.但显然你不想创建多个冗余索引.所以盲目地创建一个新的不是一个好主意.
测试存在
Postgres 9.3或更早
一种非常简单的测试方法是将模式限定名称转换为regclass
:
SELECT 'myschema.myname'::regclass
如果它抛出异常,则该名称是免费的.
或者,在DO
声明中使用的测试相同而不抛出异常:
DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relname = 'my_name' AND n.nspname = 'myschema' -- 'public' by default ) THEN CREATE INDEX my_name ON myschema.mytable (mycolumn); END IF; END$$;
这不适用于CREATE INDEX CONCURRENTLY,因为该变量不能包装在外部事务中.见下文comment by @Gregory.
Postseres 9.0引入了DO
声明.在早期版本中,您必须创建一个function才能执行相同操作.
有关pg_class
in the manual的详细信息.
关于indexes in the manual的基础知识.
Postgres 9.4
您可以使用新函数to_regclass()进行检查而不抛出异常:
DO $$ BEGIN IF to_regclass('myschema.my_name') IS NULL THEN CREATE INDEX my_name ON myschema.mytable (mycolumn); END IF; END$$;
如果该名称的索引(或另一个对象)不存在,则返回NULL.细节:
> How to check if a table exists in a given schema
Postgres 9.5
现已推出:
CREATE INDEX IF NOT EXISTS ...
这也适用于CREATE INDEX,如果不是EXISTS.
Note that there is no guarantee that the existing index is anything
like the one that would have been created.
这是对象名称的简单检查.适用于此处的所有变体.