以下是plpgsql函数的一部分。问题是source_geom
和target_geom
的结果是character varying
数据类型,因此我需要在引号中包围source_geom
和target_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
请告诉我如何解决这个问题。?
答案 0 :(得分:20)
将EXECUTE ... USING
与format()
函数及其格式说明符一起使用将使您的代码更安全,更简单,更易于阅读,而且可能更快。
SQL INJECTION WARNING :如果您接受最终用户的source_geom
或target_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;