【发布时间】:2014-07-10 10:32:30
【问题描述】:
我想在 PostgreSQL 中做类似的事情
CREATE UNIQUE INDEX IF NOT EXISTS
有什么想法吗?
【问题讨论】:
-
从 Postgres 9.5 开始,这是可能的:postgresql.org/docs/9.5/static/sql-createindex.html
标签: sql postgresql ddl
我想在 PostgreSQL 中做类似的事情
CREATE UNIQUE INDEX IF NOT EXISTS
有什么想法吗?
【问题讨论】:
标签: sql postgresql ddl
您可以通过此语句检查具有给定名称的索引是否存在。
如果您的索引名称是some_table_some_field_idx
SELECT count(*) > 0
FROM pg_class c
WHERE c.relname = 'some_table_some_field_idx'
AND c.relkind = 'i';
从 Postgres 9.5 开始,您甚至可以使用
CREATE INDEX IF NOT EXISTS
【讨论】:
只是另一种即用型解决方案。
PostgreSQL v9.0+:
DO $BLOCK$
BEGIN
BEGIN
CREATE INDEX index_name ON table_name( column_name );
EXCEPTION
WHEN duplicate_table
THEN RAISE NOTICE 'index ''index_name '' on table_name already exists, skipping';
END;
END;
$BLOCK$;
PostgreSQL v9.5+:
CREATE INDEX IF NOT EXISTS index_name ON table_name( column_name );
【讨论】:
我已经用 PLSQL 函数包装了 a_horse_with_no_name 的代码,以便更方便地使用。我希望有人会觉得它有用。
CREATE OR REPLACE FUNCTION create_index(table_name text, index_name text, column_name text) RETURNS void AS $$
declare
l_count integer;
begin
select count(*)
into l_count
from pg_indexes
where schemaname = 'public'
and tablename = lower(table_name)
and indexname = lower(index_name);
if l_count = 0 then
execute 'create index ' || index_name || ' on ' || table_name || '(' || column_name || ')';
end if;
end;
$$ LANGUAGE plpgsql;
用法: select create_index('my_table', 'my_index_name', 'id');
【讨论】:
为此,您需要一些程序代码,例如(未经测试!):
do
$$
declare
l_count integer;
begin
select count(*)
into l_count
from pg_indexes
where schemaname = 'public'
and tablename = 'your_table'
and indexname = 'your_index_name';
if l_count = 0 then
execute 'create unique index public.your_index_name on public.your_table(id)';
end if;
end;
$$
【讨论】:
create index if not exists ...(如果有这样的语法)也不会检查。
create index [aa] on bb(cc,dd) WHERE NOT EXISTS ( select ... FROM catalogs xx WHERE (something with {bb,cc,dd} ) ); 并且仍然存在共享相同 {bb,cc,dd} 值的唯一/非唯一索引的可能问题。和索引方法...
如果您仍然停留在以前的版本中,我建议您不要使用 count,而只是直接在您的 if 条件下进行查询。使代码更简单。你可以试试这样:
do
$$
begin
if not exists (
select indexname
from pg_indexes
where schemaname = 'schemaname'
and tablename = 'tablename'
and indexname = 'indexname'
)
then
create unique indexname (...);
end if;
end
$$;
【讨论】:
另一种支持多列索引的解决方案,基于@Kragh 的回答
CREATE or replace FUNCTION create_index(_index text, _table text, VARIA
DIC param_args text[]) RETURNS void AS
$$
declare
l_count integer;
begin
select count(*) into l_count
from pg_indexes
where schemaname = 'public'
and tablename = lower(_table)
and indexname = lower(_index);
if l_count = 0 then
EXECUTE format('create index %I on %I (%s)', _index, _table, array_to_string($3,','));
end if;
END;
$$
LANGUAGE plpgsql;
然后你可以像使用任何其他 pg 函数一样使用它:
select create_index('events_timestamp_type_idx', 'events', 'timestamp', 'type');
【讨论】: