0

plpgsql 関数に入る配列パラメータに問題があります。私のコードは PostgreSQL 8.3 で動作しますが、9.2.1 サーバーで呼び出すと失敗します。

問題を示すダミー関数を作成しました。これは、私が書いた最初の plpgsql コードのいくつかに基づいています。私はそれが醜いことを知っているので、両方のサーバー バージョンで機能するように引用符をエスケープできない場合は、両方のサーバー バージョンで機能するようにこのコードを書き直すことについての提案をお待ちしています。実際、私はどんな提案にもオープンです。私はplpgsqlがあまり得意ではありません

したがって、問題を示すダミーコードは次のとおりです。

CREATE OR REPLACE FUNCTION get_test(collection text[])  
  RETURNS text AS  
$BODY$   
DECLARE   
counter int8; directive text; condition text; querytype text;   
BEGIN   
    counter = array_lower(collection, 1);   
    WHILE (counter <= array_upper(collection, 1)) LOOP   
        SELECT INTO directive  "?column?"[counter] FROM (SELECT collection) AS foo ;   
        counter = counter + 1;   
        SELECT INTO condition  "?column?"[counter] FROM (SELECT collection) AS foo ;   
        counter = counter + 1;   
        SELECT into querytype  "?column?"[counter] FROM (SELECT collection) AS foo ;   
        counter = counter + 1;   
    END LOOP;   
    RETURN 'dummy';   
END;   
$BODY$  
  LANGUAGE plpgsql VOLATILE  
  COST 100;  
ALTER FUNCTION get_test(text[]) OWNER TO postgres; 

コレクション パラメーターは、3 つのセット (単純な文字列、SQL 条件、および別の文字列) で構築されます。8.3 で機能し、9.2 で失敗する呼び出しの例を次に示します。

select * from get_test('{"dynamic","(tr.PROJECT_NAME = \'SampleProject\')","1"}') 

これにより、8.3 では期待どおりに「ダミー」が返されますが、9.2 では次のように失敗します: ERROR: syntax error at or near "SampleProject"埋め込み SQL の一重引用符が正しく含まれていることを確認してください。

一重引用符の前にバックスラッシュを付けずに、2 つのバックスラッシュを付けて、最後に 2 つの一重引用符を付けて試してみましたが、すべて役に立ちませんでした。元のコードは Java クライアントによって呼び出されますが、これを pgadmin3 (バージョン 1.16) でテストし、問題のバージョンの 2 つのサーバーに接続して、さまざまなことを試しました。

この通話を機能させる方法についてのアイデアはありますか?

4

1 に答える 1

1

最も可能性の高い理由は、 の設定が異なることですstandard_conforming_strings
この呼び出しを試してください:

単一引用符で囲まれた文字列リテラル内の単一引用符をエスケープする SQL 標準の方法 (および PostgreSQL で推奨) は、それらを二重にすることです。

SELECT *
FROM get_test('{dynamic,(tr.PROJECT_NAME = ''SampleProject''),1}'::text[])

また:

SELECT *
FROM get_test('{dynamic,"(tr.PROJECT_NAME = ''SampleProject'')",1}'::text[])

または、引用符をエスケープする複数のレイヤーを避けるために、ドル引用符に頼ることができます

SELECT *
FROM get_test($${dynamic,"(tr.PROJECT_NAME = 'SampleProject')",1}$$::text[])

または、ARRAY コンストラクターでさえ:

SELECT *
FROM get_test(ARRAY['dynamic','(tr.PROJECT_NAME = ''SampleProject'')','1'])
于 2013-01-03T17:46:52.557 に答える