5

以下是 plpgsql 函数的一部分。问题是source_geomand的结果target_geom是一种character varying数据类型,因此我需要将source_geomandtarget_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

请任何建议我如何解决这个问题。?

4

2 回答 2

21

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


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


如果您使用的是具有该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_literal/quote_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 回答