2015-11-06 114 views
1

我創建了一個功能remove_tables這是如下圖所示EXECUTE失敗未來不會繼續

CREATE OR REPLACE FUNCTION remove_tables (integer) 
    RETURNS void AS 
$BODY$DECLARE  
    _id ALIAS FOR $1; 
BEGIN 
    EXECUTE 'DROP TABLE something_' || _id || ' CASCADE'; 
    DELETE FROM lot WHERE id = _id ; 
END;$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION delete_tables(integer) 
    OWNER TO postgres; 

我的問題是,EXECUTE可能失敗,但我還是想用DELETE語句來進行(DELETE FROM很多WHERE ID = _id;)

我嘗試使用PERFORM'DROP TABLE something_'|| _id || 'CASCADE';但並沒有給我想要什麼

有什麼我可以做,執行一個語句,無論成功還是失敗,而且還與其他發言

+0

你需要一個異常處理程序:HTTP://www.postgresql .ORG /文檔/電流/靜態/ plpgsql- control-structures.html#PLPGSQL-ERROR-TRAPPING(你還需要設置一個保存點,以便在發生錯誤時繼續進行交易) –

+0

好的,謝謝,我試圖捕捉異常並且什麼都不做,看起來不錯對於我需要的 – hghew

+0

如果你想要的是防止錯誤,如果表不存在,使用'drop table if exists ...' –

回答

0

你需要把例外圍繞你期望失敗塊處理進行。

CREATE OR REPLACE FUNCTION remove_tables (integer) 
    RETURNS void AS 
$BODY$DECLARE  
    _id ALIAS FOR $1; 
BEGIN 
    BEGIN 
    EXECUTE 'DROP TABLE something_' || _id || ' CASCADE'; 
    EXCEPTION WHEN read_only_sql_transaction THEN 
    -- Do nothing 
    END; 
    DELETE FROM lot WHERE id = _id ; 
END;$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION delete_tables(integer) 
    OWNER TO postgres; 

請參閱文檔http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html(40.6.6。陷印錯誤)。

查看http://www.postgresql.org/docs/9.1/interactive/errcodes-appendix.html瞭解異常代碼。

+0

好的,謝謝,那是@a_horse_with_no_name上面指出的,謝謝你的回答:)順便說一下,異常陷阱是否有任何性能問題? – hghew

+0

是的,只是認爲添加更完整的答案將有助於任何人在未來尋找解決方案類似的問題。我沒有意識到任何性能問題,但是如果經常刪除表,可以先添加一個檢查以確保表存在並可以刪除。 – Onots

+0

謝謝:)我有檢查表存在,它也適用。 – hghew

1

我已經試過了異常陷阱指出的@a_horse_with_no_name和@Onots,使用異常捕獲做工不錯

我也試圖通過@Onots提到的檢查表中的其他方法的存在與否,也工作好

由於我不知道關於誘捕例外會對性能產生任何影響,我已經使用該檢查表的代碼存在之前放棄它

CREATE OR REPLACE FUNCTION remove_tables (integer) 
    RETURNS void AS 
$BODY$DECLARE  
    _id ALIAS FOR $1; 
BEGIN 
    IF EXISTS(SELECT * FROM information_schema.tables WHERE table_name = something_' || _id) THEN 
     EXECUTE 'DROP TABLE something_' || _id || ' CASCADE'; 
    ENDIF; 
    DELETE FROM lot WHERE id = _id ; 
END;$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION delete_tables(integer) 
    OWNER TO postgres; 
+1

爲什麼不簡單地使用'drop table if exists ...'而不是? –

+0

好的,謝謝你給我一個更好的方法,我用來檢查表存在之前執行一些其他語句:)無論如何感謝指出這 – hghew