2015-04-28 40 views
3

我試圖根據條件在啓動時刪除表:如何在postgres中基於IF條件刪除表?

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

結果:Syntaxerror at 'IF', SQL state: 42601。爲什麼?如果我不允許使用IF,我該如何根據條件放置一張桌子?

+0

'drop table if exists'只有在存在的情況下才會刪除表,因此您可以刪除'if if exists'...' –

+0

我只想在表狀態爲'UNLOGGED'時刪除表,因此確實需要事先選擇... – membersound

回答

5

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條件,以確保您不會意外地從錯誤的架構刪除表。

+0

好的,我明白了,非常感謝。我將如何創建連接? 'select * from pg_namespace' would give me the following:'nspname nspowner nspacl'' public 10「{postgres = UC/postgres,= UC/postgres}」',我當然只想在「public」架構。 – membersound

+1

@membersound:看我的編輯 –

+1

不能做得更短,IF EXISTS(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'); 

select drop_table('mytable_1')