2017-08-07 12 views
0

コードをサニタイズするためにplpgsqlでプリペアドステートメントを実行する方法を理解しようとしています。それが何かあるならば、私は、すぐにこの時に新しいフリークアウトしないでください午前PostgreSQLの準備文

DECLARE 
tags_query text := 'true'; 
BEGIN 
     IF char_length(search_term) > 0 THEN 
      order_by := 'ts_rank_cd(textsearchable_index_col, to_tsquery(''' || search_term || ':*''))+GREATEST(0,(-1*EXTRACT(epoch FROM age(last_edited)/86400))+60)/60 DESC'; 
      search_term := 'to_tsquery(''' || search_term || ':*'') @@ textsearchable_index_col'; 
     ELSE 
      search_term := 'true'; 
     END IF; 
... 

PREPARE statements(text, text, text, text, text, text, text, text, text, text, text, text) AS 
         'SELECT 
          * 
         FROM 
          articles 
         WHERE 
          ' || $1 || ' AND 
          ' || $2 || ' AND 
          primary_category LIKE ''' || $3 || ''' AND 
          ' || $4 || ' AND 
          ' || $5 || ' AND 
          ' || $6 || ' AND 
          ' || $7 || ' AND 
          ' || $8 || ' AND 
          ' || $9 || ' AND 
          ' || $10 || ' AND 
          ' || $11 || ' AND 
          is_template = ' || §12 || ' AND 
          status <> ''DELETED'' 
         ORDER BY ' || $13 || ' LIMIT 500'; 

        RETURN QUERY EXECUTE statements(search_term, publication_date_query, category_filter, tags_query, districts_query, capability_query, push_notification_query, distance_query, revision_by, publication_priority_query, status_query, only_templates, order_by); 

上記のコードは、私はそうのように私の変数をdeclade

ERROR: syntax error at or near "'SELECT 
         * 
        FROM 
         articles 
        WHERE 
         '" 
LINE 67:  'SELECT 

を返します。愚かな、私は気付かなかった。

編集:PostgreSQLのバージョン9.6

編集:私はdocumentationの承知しています。

+0

達成したいことはありますか? –

+0

私は自分のユーザー入力をサニタイズしたい。 @ UsagiMiyamoto私は、準備されたステートメントはVS SQLインジェクションに行く方法です読んだ。 – Spacemoose

+0

準備文を構成するために連結を行う必要はありません。リンクされたドキュメントでは、最初の例で '$ 1'から' $ 4'をそのままステートメントで使用する方法を参照してください。私はあなたがパラメータとして($ 1' = 'COLUMN = VALUE'と' $ 1 AND ... ')文全体を指定することはできませんが、あなたのステートメントで 'VALUE'と' COLUMN = $ 1 AND ... ')、私は間違っているかもしれないのであなたがリンクしている文書で指定されたものを見つけることができません。 – Aaron

答えて

0

多くの問題があります。

  1. plpgsqlが明示的に作成したコマンドをサポートしていません - そうSQL EXECUTEコマンドがplpgsqlがEXECUTEコマンドとは異なります。 PLpgSQL EXECUTEコマンドのパラメータはSQL文字列であり、準備されたコマンドの名前ではありません。 PLpgSQLから明示的に準備されたSQLを実行するには、クリーンな方法はありません。したがって、PLpgSQLのPREPARE cmd(); EXECUTE cmd()の組み合わせには意味がありません。
  2. 準備されたステートメントのパラメータは、クリーンな値でなければなりません。アポストロフィ内では使用できません。 `` $ n 'は別のナンセンスです。ちょうど$ nは安全です。 '$ n'は文字列 "$ n"を意味し、あなたが予想しているよりもおそらく異なっています。