如何在PostgreSQL函数中声明一个字符串?

时间:2017-05-23 15:19:49

标签: postgresql

我试图构建一个更新经度和纬度的PostgreSQL函数,并为给定用户使用lat / lon对设置PostGIS几何点:

CREATE OR REPLACE FUNCTION set_user_geom(uid integer, lat double precision, lon double precision)
RETURNS void AS
$$
UPDATE profile SET home_lon = $3 WHERE user_id = $1;
UPDATE profile SET home_lat = $2 WHERE user_id = $1;
UPDATE profile SET home_point = 'SRID=4326;POINT($3 $2)' WHERE user_id = $1;
$$
LANGUAGE 'sql';

当我尝试在psql控制台中创建函数时,出现以下错误:

ERROR: parse error - invalid geometry
LINE 6: UPDATE personal_profile SET home_point = 'SRID=4326;POINT($3...
                                                 ^
HINT: "SRID=4326;POINT($3)" <-- parse error at position 18 within geometry

我已经查看了PostgreSQL文档,但没有找到答案。我还尝试使用另一个单引号以及反斜杠来避免每个单引号,但是没有修复它。

如果我运行使用有效参数从命令行设置home_point的命令,它就可以正常工作。

任何人都可以看到我做错了吗?

1 个答案:

答案 0 :(得分:2)

Postgres没有进行任何字符串插值:字符串'SRID=4326;POINT($3 $2)'的字面意思是'SRID=4326;POINT($3 $2)',但您希望它实际上&#34;填写&#34; $3$2,因此它变成'SRID=4326;POINT(-10.2 42.5)'

您需要做的就是使用||运算符(不要忘记空格)连接变量和字符串的固定部分。但是,您还需要将它们转换为text以避免类型不匹配错误:

... SET home_point = 'SRID=4326;POINT(' || Cast($3 as text) || ' ' || Cast($2 as text) || ')' ...

或者使用Postgres的非标准::强制转换操作符,我发现它非常易读:

... SET home_point = 'SRID=4326;POINT(' || $3::text || ' ' || $2::text || ')' ...

还有a format function,它有点像sprintf:你给它一个带有一些占位符的字符串,它填充了部分。它接受任何参数类型,并不要求您首先转换为text

... SET home_point = format('SRID=4326;POINT(%s, %s)', $3, $2) ...

然后,您可能必须将连接的字符串显式转换为geometry类型:

... SET home_point = Cast( 'SRID=4326;POINT(' || Cast($3 as text) || ' ' || Cast($2 as text) || ')' as geometry ) ...
... SET home_point = ('SRID=4326;POINT(' || $3::text || ' ' || $2::text || ')')::geometry ...
... SET home_point = Cast(format('SRID=4326;POINT(%s, %s)', $3, $2) as geometry) ...
... SET home_point = format('SRID=4326;POINT(%s, %s)', $3, $2)::geometry ...