5

以下はplpgsql関数の一部です。問題は、との結果がsource_geomデータtarget_geom型であるため、両方と引用符('')でcharacter varying囲む必要があることです。問題は、plpgsql言語では、どうすればそれができるかわからないということです。 これが私が現在持っているものです:source_geomtarget_geom

 EXECUTE 'update ' || quote_ident(geom_table) || 
        ' SET source = ' || source_geom || 
        ', target = ' || target_geom ||
        ' WHERE ' || quote_ident(gid_cname) || ' =  ' || _r.id;

私が抱えているエラーは次のとおりです。

ERROR:  syntax error at or near "C03B9E3B66052D400DDEFC2BD0F24140"
LINE 1: ...pdate track_points SET source = 0101000020E6100000C03B9E3B66...
                                                             ^
QUERY:  update track_points SET source = 0101000020E6100000C03B9E3B66052D400DDEFC2BD0F24140, target = 0101000020E610000075690DEF83052D40F88E75CCD4F24140 WHERE ogc_fid =  2
CONTEXT:  PL/pgSQL function "create_network" line 26 at EXECUTE statement

この問題を解決する方法を提案してください。

4

2 に答える 2

21

関数とそのフォーマット指定子を使用EXECUTE ... USINGするとformat()、コードがはるかに安全で、単純になり、読みやすくなり、おそらく高速になります。


SQLインジェクション警告:エンドユーザーを受け入れるsource_geomか、エンドユーザーから受け取る場合、コードはSQLインジェクションtarget_geomに対して潜在的に脆弱です。SQLインジェクション攻撃を防ぐために、パラメーター化されたステートメント(など)を使用するか、それを失敗した場合は、パラノイド引用符を使用することが重要です。関数がユーザー入力を受け取るとは思わない場合でも、アプリがどのように進化するかわからないため、SQLインジェクションに対して関数を強化する必要があります。EXECUTE ... USING


formatこの関数を使用して新しいPostgreSQLを使用している場合は、コードを次のように大幅に簡略化できます。

EXECUTE format('update %I SET source = %L, target = %L WHERE %I = %L',
    geom_table, source_geom, target_geom, gid_cname, _r.id);

...これは、フォーマット指定子を使用して識別子(%I)とリテラル( )の引用を処理するため、ひどい連結や/のもの%Lをすべて記述する必要はありません。||quote_literalquote_ident

次に、のドキュメントEXECUTE ... USINGに従って、クエリを次のようにさらに絞り込むことができます。

EXECUTE format(
    'update %I SET source = $1, target = $2 WHERE %I =  $3',
    geom_table, gid_cname
) USING source_geom, target_geom, _r.id;

これにより、クエリがパラメータ化されたステートメントに変わり、パラメータが識別子から明確に分離され、文字列の処理コストが削減されて、より効率的なクエリが実現します。

于 2012-10-21T06:01:27.990 に答える
3

追加の引用符を使用します。

EXECUTE 'update ' || quote_ident(geom_table) || 
        ' SET source = ''' || source_geom || ''' 
        , target = ''' || target_geom || '''
        WHERE ' || quote_ident(gid_cname) || ' =  ' || _r.id;
于 2012-10-20T17:23:26.030 に答える