在PL / PgSQL EXECUTE动态查询中正确插入文字

时间:2012-10-20 16:54:01

标签: sql postgresql plpgsql dynamic-sql

以下是plpgsql函数的一部分。问题是source_geomtarget_geom的结果是character varying数据类型,因此我需要在引号中包围source_geomtarget_geom( '')。问题是在plpgsql语言中我怎么不知道我能做到 这就是我现在所拥有的:

 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

请告诉我如何解决这个问题。?

2 个答案:

答案 0 :(得分:20)

EXECUTE ... USINGformat()函数及其格式说明符一起使用将使您的代码更安全,更简单,更易于阅读,而且可能更快。


SQL INJECTION WARNING :如果您接受最终用户的source_geomtarget_geom,则您的代码可能容易受到SQL injection的攻击。使用参数化语句(如EXECUTE ... USING)或失败,偏执引用以防止SQL注入攻击非常重要。即使你不认为你的函数需要用户输入,你仍然应该强化SQL注入,因为你不知道你的应用程序将如何发展。


如果您使用format function使用较新的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)引用,因此您不必编写所有可怕的||并置和{ {1}} / quote_literal内容。

然后,根据the documentation on EXECUTE ... USING,您可以进一步优化查询:

quote_ident

将查询转换为参数化语句,明确地将参数与标识符分开,并降低字符串处理成本,以实现更高效的查询。

答案 1 :(得分:2)

使用额外报价:

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