2012-01-17 15 views
1

この質問は約Postgresql 8.3です。if文に条件が含まれる文字列

私は 'lastcontact is null'のような条件を含むフィールドを持つテーブルを持っています。この例のように、コードでは、私はこのテーブルをループにしたいとレコードごとに、I「は、もし条件」を確認したい:

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   | ... | ... 

私が望むチェックは可能ですか?次のエラーで結果上記のコード:私は取得

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: invalid input syntax for type boolean: "lastcontact is null" 
このエラー:

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

これはテーブル定義ではありませんが、3つのサンプル行を示しています。フィールド 'conditie'に 'lastcontact Leonard

+0

エラーメッセージが示すとおり、このフィールドの型は 'boolean'です。したがって、 'NULL'、' TRUE'または 'FALSE'を含むことができます。他のものはありません。特に、 '' lastcontact

+0

列は文字列です。私は文字列を取得し、私に 'FALSE'の' TRUE'を与えます。文字列には条件が含まれています。コード内でlastcontact Leonard