我正在使用PostGIS在PostgreSQL中创建一个函数,我接受表名和点的几何,我想在函数内部的查询中使用它们......
CREATE OR REPLACE FUNCTION trial(tbl text[],tag text[],geo geometry)
RETURNS boolean AS
$BODY$
DECLARE i integer;
DECLARE len integer;
DECLARE result boolean;
DECLARE bool boolean;
BEGIN
result=true;
SELECT ARRAY_LENGTH(tbl,1) INTO len;
FOR i IN 1..len LOOP
EXECUTE format('select st_dwithin(geo::geography,geom::geography,1) from %s where name=any(array[%s]) and st_dwithin(geo::geography,geom::geography,1)=true',tbl[i],tag[i]) into bool;
IF (bool!=true) THEN
result=false;
EXIT;
END IF;
END LOOP;
return result;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
这显示错误为
LINE 1: select st_dwithin(geo::geography,geom::geography,1) from grn...
当我使用
时该几何的%s
我收到了下一个错误
ERROR: syntax error at or near "AA40E9A0E5440F498329474092A40"
LINE 1: select st_dwithin(0101000020E6100000002AA40E9A0E5440F4983294...
我是PostgreSQL的初学者...在这种情况下我可以使用什么格式说明符?????
答案 0 :(得分:1)
您的功能存在一些问题。
首先,在format()
函数中,您只能传递标识符和文字值,而需要传递函数的geography
和text[]
两个参数。这基本上意味着您无法使用format()
功能,但您应该use the USING
clause。顺便说一下,这是个好消息,因为format()
生成一个字符串并且效率非常低(你传入一个geometry
,它被format()
转换为字符串,然后被解析回{ {1}}在服务器中,每次迭代循环一次)。作为PL / pgSQL变量的geometry
参数将不会由geo
解析,因此它也必须通过EXECUTE
子句提供。
动态查询本身也不是特别好。逻辑表示如果USING
中至少有一行距true
1米范围内,则要返回tags
。有效编写,该查询将是:
geo
这显然假设所有表格都有SELECT 1 FROM <table>
WHERE name = ANY(<tags>)
AND ST_DWithin(<geo>, geom::geography, 1, false)
LIMIT 1;
和name
列。如果geom
属于geom
类型,则可以省略强制转换。使用geography
进行球体计算,这对于这个短距离来说已经足够了,而且计算起来要快得多。
与一些流逻辑改进一起,您的功能变为:
false
此函数采用一组表名,然后确定所有表是否在指定点的1米范围内具有任何提供的标记至少1个点。这对我来说听起来不太有用。返回一组CREATE OR REPLACE FUNCTION trial(tbl text[], tag text[], geo geography)
RETURNS boolean AS $BODY$
DECLARE
t text;
res int;
BEGIN
FOREACH t IN ARRAY tbl LOOP
EXECUTE 'SELECT 1 FROM ' || quote_ident(t) ||
' WHERE name = ANY($1)' ||
' AND ST_DWithin($2, geom::geography, 1, false) ' ||
'LIMIT 1'
INTO res USING tags, geo;
IF res IS NULL THEN -- No value was returned so no nearby points
RETURN false;
END IF;
END LOOP;
RETURN true; -- If we get here, all tables have at least 1 match
END;
$BODY$ LANGUAGE plpgsql;
,每行给出满足该条件的表的名称,看起来更有用,或者甚至是text
版本,为每个表提供数字1米内的点数和该表的匹配标签。