2012-01-17 34 views
1

這個問題是關於Postgresql 8.3if-statement包含條件的字符串

我有一個表中包含像'lastcontact爲空'的條件的字段。在代碼中,我想遍歷這個表,併爲每個記錄,我要檢查「如果條件那麼」,就像這個例子:

FOR myrec IN 
    SELECT * FROM tabel ORDER BY colorlevel, volgnummer 
LOOP 
    if (myrec.conditie) then 
     raise notice 'Condition % is true', myrec.conditie; 
    else 
     raise notice 'Condition % is false', myrec.conditie; 
    end if; 
END LOOP; 

這是我在這個例子中被稱爲「TABEL」表:

ID | Conditie    | Colorlevel | Volgnummer | Code | Description 
1 | lastcontact is null | 1   | 1   | ... | ... 
2 | lastchanged is null | 1   | 2   | ... | ... 
3 | lastmodified is null | 1   | 3   | ... | ... 

是否可以做我想要的支票?以下錯誤上述結果的代碼:

ERROR: invalid input syntax for type boolean: "lastcontact is null" 

包含歐文的函數的結果,新科

我已經使用這個功能:

CREATE OR REPLACE FUNCTION foo(lastcontact timestamptz) 
    RETURNS void AS 
$BODY$ 
DECLARE 
    myrec record; 
    mycond boolean; 
BEGIN 

FOR myrec IN 
    SELECT * FROM tabel ORDER BY colorlevel, volgnummer 
LOOP 
    EXECUTE 'SELECT ' || myrec.conditie || ' FROM tabel' INTO mycond; 

    IF mycond then 
     RAISE NOTICE 'Condition % is true', myrec.conditie; 
    ELSE 
     RAISE NOTICE 'Condition % is false', COALESCE(myrec.conditie, 'NULL'); 
    END IF; 
END LOOP; 

END; 
$BODY$ 
language 'plpgsql' volatile 
cost 100; 

我得到此錯誤:

ERROR: column "lastcontact" does not exist 
LINE 1: SELECT lastcontact is null FROM tabel 
     ^
QUERY: SELECT lastcontact is null FROM tabel 
CONTEXT: PL/pgSQL function "foo" line 9 at EXECUTE statement1 

我試圖自己找一個解釋,但無濟於事。顯然它試圖對數據庫運行語句,但它應該理解'lastcontact'是作爲函數參數給出的變量。

回答

1

從評論我終於想我明白了。您需要dynamic SQL

CREATE OR REPLACE FUNCTION foo(lastcontact timestamptz) 
    RETURNS void AS 
$func$ 
DECLARE 
    myrec record; 
    mycond boolean; 
BEGIN 

FOR myrec IN 
    SELECT * FROM tabel ORDER BY colorlevel, volgnummer 
LOOP 
    IF myrec.conditie ~~ '%lastcontact %' THEN -- special case for input param 
     myrec.conditie := replace (myrec.conditie 
         , 'lastcontact ' 
         , CASE WHEN lastcontact IS NULL THEN 'NULL ' 
          ELSE '''' || lastcontact::text || ''' ' END); 
    END IF; 

    EXECUTE 'SELECT ' || myrec.conditie || ' FROM tabel' INTO mycond; 

    IF mycond then 
     RAISE NOTICE 'Condition % is true', myrec.conditie; 
    ELSE 
     RAISE NOTICE 'Condition % is false', COALESCE(myrec.conditie, 'NULL'); 
    END IF; 
END LOOP; 

END 
$func$ LANGUAGE plpgsql; 

注意,但是,這個設置是敞開的SQL注入。只使用驗證的輸入。 函數在PostgreSQL中工作8.3(還沒有DO語句)。

您不能引用動態SQL中的參數(EXECUTE語句)。您必須將該值放入查詢字符串中。

在PostgreSQL 8.4或更高版本中,您擁有優質商品USING clause。唉,不在版本8.3中。如果可以的話,你應該考慮升級。

我爲您的舊版本提供瞭解決方法。你必須特別注意NULL的值。

+0

這不是一個表定義,但它顯示了三個示例行。如果字段'conditie'包含'lastcontact Leonard

+0

錯誤消息告訴我們該字段的類型爲「boolean」。所以它可以包含NULL,TRUE或FALSE。沒有別的,特別是不是字符串''lastcontact

+0

該列是一個字符串。我得到了字符串,它應該給我一個'FALSE'的'TRUE'。該字符串包含一個條件。如果我在代碼中說'如果lastcontact Leonard