如何在Postgres中基于IF条件删除表?

4

我正在尝试根据条件在启动时删除一个表:

IF NOT EXISTS (select * from pg_class where relname = 'mytable' and relpersistence = 'u') 
DROP TABLE IF EXISTS mytable

结果:Syntaxerror at 'IF',SQL状态:42601。为什么?如果不允许使用IF,我如何根据条件删除表格?


如果存在则删除表格,这是由“drop table if exists”实现的,因此您可以使用“if not exists…”来删除。 - A ツ
我只想在表的状态为“UNLOGGED”时才删除它,因此我确实需要先进行选择... - membersound
2个回答

6

IF不能在SQL中使用,这仅适用于PL/pgSQL。

您需要在匿名的PL/pgSQL代码块中使用动态SQL来完成此操作。例如:

do
$$
declare
  l_count integer;
begin
  select count(*)
     into l_count
  from pg_class c
    join pg_namespace nsp on c.relnamespace = nsp.oid
  where c.relname = 'mytable' 
    and c.relpersistence = 'u'
    and nsp.nspname = 'public';

  if l_count = 1 then 
    execute 'drop table mytable';
  end if;

end;
$$

您可能需要扩展 select 语句以联接 pg_namespace 并在 where 条件中包含模式名称,以确保不会意外删除错误模式中的表。


好的,我明白了,非常感谢。那么我该如何创建连接呢?执行 select * from pg_namespace 会给我以下结果:nspname nspowner nspacl public 10 "{postgres=UC/postgres,=UC/postgres}",当然我只想在 "public" 模式上执行删除操作。 - membersound
1
这个能不能缩短一些,如果存在 (SELECT 1 FROM pg_class....) 则执行......? - Jayadevan

2

已经被a_horse_with_no_name接受的答案是可行的。 如果您想在将来使用相同的任务处理其他表格,则可以创建自定义函数,因此应创建以下函数:

create or replace function drop_table (_tbl varchar) returns void as
$$
begin
if exists(select 1
          from pg_class c
          join pg_namespace nsp on c.relnamespace = nsp.oid
          where c.relname = ''||_tbl||'' 
            and c.relpersistence = 'u'
            and nsp.nspname = 'public') then
  execute format('DROP TABLE %s',_tbl);
  raise notice 'Table %s Deleted',_tbl;
else
  raise notice 'Table %s Not Deleted',_tbl;
end if;
end;
$$
language plpgsql

只需在需要的时候调用此函数即可。
select drop_table('mytable'); 

或者

选择 drop_table('mytable_1')


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接