2014-02-21 98 views
1

我已經寫了一個pl/pgsql函數來trucate表。 HIST_CLEANUP_TBL有5個table_name。 5箇中,1個table_name在數據庫中不存在。需要使用plpgsql函數截斷表

需求是:它必須檢查所有表格。如果表不存在,則將錯誤寫入錯誤表並截斷剩餘的表。

但是,在這裏,當不可用表進入循環時,函數終止。

如何捕獲變量中的錯誤代碼和文本以及如何通過1個表不存在來繼續循環。

我們使用的是錯誤的PostgreSQL 8.2

BEGIN 

    for recordvar in 
    SELECT 'truncate table ' || TABLE_NAME as SQRY FROM HIST_CLEANUP_TBL 
    loop 
     QUERY1 := recordvar.SQRY; 
     RAISE NOTICE 'QUERY: (%)', QUERY1;  

     BEGIN 
     execute QUERY1; 
     RAISE NOTICE 'QUERY EXECUTED SUCCESSFULLY'; 
     EXCEPTION 
     WHEN others 
     THEN 
     --GET STACKED DIAGNOSTICS 
     ERR_NUM := SQLSTATE; 
     ERR_MESG := SQLERRM ; 

     RAISE NOTICE 'ERROR WHILE EXECUTING THE QUERY : %',ERR_NUM; 

     insert into Refresh_Error_tbl(sqlerr_code,sqlerr_desc,sql_desc, INSERT_DT,refresh_load_id) values(ERR_NUM,ERR_MESG,QUERY1,current_timestamp,'1'); 
     END; 
     end loop; 
END; 
+0

是否有可能你的例外條款本身拋出異常?例如,如果插入錯誤?如果異常處理程序內有異常,那麼肯定會中止 – harmic

+0

這裏問題是它沒有進入異常循環。 – user3145945

+0

HIST_CLEANUP_TBL TABLE_NAME 甲 乙 Ç d Ë 這裏,C表能源部不存在於數據庫中。當C到達終止函數並且表D和E不被截斷時,函數正在爲表A和B運行。 因此需要將表C寫入錯誤表和進程D和E – user3145945

回答

1

原因一定在別處。下面的代碼工作正常:

CREATE TABLE hist_cleanup (
    table_name text 
); 

CREATE TABLE table_a(); 
CREATE TABLE table_b(); 
-- table_c missing 
CREATE TABLE table_d(); 
CREATE TABLE table_e(); 

INSERT INTO hist_cleanup 
VALUES 
    ('table_a') 
, ('table_b') 
, ('table_c') 
, ('table_d') 
, ('table_e'); 

CREATE TABLE refresh_error (
    sqlerr_code  text 
, sqlerr_desc  text 
, sql_desc  text 
, insert_dt  timestamp 
, refresh_load_id int 
); 

CREATE OR REPLACE FUNCTION cleanup() 
RETURNS VOID AS $$ 
DECLARE 
    _rec record; 
    _query text; 
BEGIN 

    FOR _rec IN (
     SELECT table_name 
     FROM hist_cleanup 
    ) LOOP 
     _query := 'TRUNCATE TABLE ' || _rec.table_name; 

     RAISE NOTICE 'QUERY: (%)', _query;  

     BEGIN 
      EXECUTE _query; 
      RAISE NOTICE 'QUERY EXECUTED SUCCESSFULLY'; 
     EXCEPTION 
      WHEN OTHERS 
      THEN 
       RAISE NOTICE 'ERROR WHILE EXECUTING THE QUERY: % %', SQLSTATE, SQLERRM; 
       INSERT INTO refresh_error (
        sqlerr_code 
       , sqlerr_desc 
       , sql_desc 
       , insert_dt 
       , refresh_load_id) 
       VALUES (
        SQLSTATE 
       , SQLERRM 
       , _query 
       , CURRENT_TIMESTAMP 
       , '1' 
       ); 
     END; 
    END LOOP; 

    RETURN; 

END $$ LANGUAGE plpgsql; 

SELECT cleanup(); 

輸出:

NOTICE: QUERY: (TRUNCATE TABLE table_a) 
NOTICE: QUERY EXECUTED SUCCESSFULLY 
NOTICE: QUERY: (TRUNCATE TABLE table_b) 
NOTICE: QUERY EXECUTED SUCCESSFULLY 
NOTICE: QUERY: (TRUNCATE TABLE table_c) 
NOTICE: ERROR WHILE EXECUTING THE QUERY: 42P01 relation "table_c" does not exist 
NOTICE: QUERY: (TRUNCATE TABLE table_d) 
NOTICE: QUERY EXECUTED SUCCESSFULLY 
NOTICE: QUERY: (TRUNCATE TABLE table_e) 
NOTICE: QUERY EXECUTED SUCCESSFULLY 
+0

感謝您的解決方案,我將重新編寫函數 – user3145945

+0

您好Tomasz,我根據您的建議它重新編碼函數運行良好。問題是我無法將SQLSTATE和SQLERRM存儲到變量中。當我試圖存儲它拋出的錯誤,如果我們忽略thne它運行良好 – user3145945

+0

很高興聽到它。至於用於存儲SQLSTATE和SQLERRM變量值的變量,可能它們沒有被聲明或者被聲明爲不合適的類型?無論如何,我認爲你可以接受我的答案。 –