6

私はPostgresに関数を持っています:

CREATE OR REPLACE FUNCTION upsert(sql_insert text, sql_update text) 
RETURNS integer AS
$BODY$
BEGIN
 EXECUTE sql_insert;
 RETURN 1;
EXCEPTION WHEN unique_violation THEN
 EXECUTE sql_update; 
 RETURN 2;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
ALTER FUNCTION upsert(text, text) OWNER TO dce;

私は通常、このクエリを使用してその関数を呼び出します。

select upsert(
  $$INSERT INTO zz(a, b) VALUES (66, 'hahahaha')$$,
  $$UPDATE zz SET a=66, b='hahahaha' WHERE a=66$$
)

できます。残念ながら、次のようにクエリ文字列に を含めることはできません$$

select upsert(
  $$INSERT INTO zz(a, b) VALUES (66, 'ha$$hahaha')$$,
  $$UPDATE zz SET a=66, b='hahahaha' WHERE a=66$$
)

私はこのPostgres のドキュメントを読みましたが、その方法についてまだ支援が必要です。

4

1 に答える 1

12

代わりに別のドル引用符を使用してください。

select upsert(
    $unique_token$ INSERT INTO zz(a, b) VALUES (66, 'ha$$hahaha') $unique_token$ ,
    $unique_token2$ UPDATE zz SET a=66, b='hahahaha' WHERE a=66 $unique_token2 $
   )

各エンドは各スタートと一致する必要があります。2 つのペアが異なる必要はありませんが、その方が安全です。

これにより、ドル引用符が文字列内で一致する可能性が理論的に残っています。

手動でクエリを作成している場合は$、文字列をチェックするだけです。変数からクエリを作成している場合は、quote_literal(querystring)代わりに使用できます。

便利な機能もありformat()ます。

見る:

余談ですが、この形式の動的 SQL は SQL インジェクションに対して非常に脆弱であることをご存知でしょうか? この種のものは、非常にプライベートな、または非常に安全な使用にのみ使用する必要があります。

于 2012-02-14T05:15:42.990 に答える