0

Can anyone see what's wrong with the below simple function? Is it a simple syntax error or something else? I'm using postgreSQL 8.4. Thanks in advance

CREATE OR REPLACE FUNCTION get_source_from_closest_road_to_point(IN point geometry)
  RETURNS integer AS
$BODY$
      DECLARE --- Nothing to declare
          query varchar;
          rec RECORD;
      BEGIN

      query = 'SELECT p.source FROM project AS p
                         WHERE ST_CONTAINS(ST_BUFFER('|| $1 ||',0.001),p.the_geom)
                         AND p.clazz NOT IN (''11'',''12'') -- Motorway or motorway entrance exit ways
                         ORDER BY st_distance(st_closestpoint(p.the_geom::geometry, '|| $1 ||'::geometry), '|| $1 ||'::geometry) ASC  LIMIT 1';

      FOR rec IN EXECUTE query LOOP
           RETURN rec.source;
      END LOOP;

      END;   $BODY$
LANGUAGE 'plpgsql' VOLATILE

I'm using the command:

     explain analyze select * from get_source_from_closest_road_to_point(ST_GeomFromText('Point(-6.3047272 53.4030415)', 4326));

But get the error:

   ERROR:  operator is not unique: unknown || geometry
   LINE 2: ...                     WHERE ST_CONTAINS(ST_BUFFER('||  $1  ||...
                                                         ^
   HINT:  Could not choose a best candidate operator. You might need to add explicit      type casts.
   QUERY:  SELECT  'SELECT p.source FROM project AS p
                         WHERE ST_CONTAINS(ST_BUFFER('||  $1  ||',0.001),p.the_geom)
                         AND p.clazz NOT IN (''11'',''12'') -- Motorway or motorway   entrance exit ways
    '||  $1  ||'::geometry), '||  $1  ||'::geometry) ASC  LIMIT 1'
      C         ONTEXT:  PL/pgSQL function "get_source_from_closest_road_to_point" line 6 at assignment

      ********** Error **********

     ERROR: operator is not unique: unknown || geometry
      SQL state: 42725 
4

2 回答 2

1

如果要动态构建查询字符串然后执行它,另一种方法是将几何转换为文本,然后再次返回几何,以便在构建字符串时将其解释为文本字符,然后实际执行时转换回几何图形。这有点难看,但确实有效,因为我在使用 geom 方法执行 '... $1 ...' 时遇到了一些问题,例如,

stmt:='... st_contains(st_geomfromtext(''' || st_astext(geom_param) || '''),geom)...'
execute stmt;

我的用例是我必须动态生成 csv 文件的保存名称,使用 copy... 到文件名和封闭几何图形来自作为参数传入的表的位置,所以我无法避免循环和这样的动态SQL创建。

于 2013-10-28T17:46:42.523 回答
0

尝试使用带参数的动态 SQL。就像是:

CREATE OR REPLACE FUNCTION get_source_from_closest_road_to_point(IN point geometry)
  RETURNS integer AS
$BODY$
DECLARE
  src integer;
BEGIN
   EXECUTE 'SELECT p.source FROM project AS p
            WHERE ST_CONTAINS(ST_BUFFER($1 ,0.001),p.the_geom)
              AND p.clazz NOT IN (''11'',''12'') -- Motorway or motorway entrance exit ways
            ORDER BY st_distance(st_closestpoint(p.the_geom::geometry, $1), $1) ASC  
            LIMIT 1' 
   INTO src
   USING point;
   RETURN src;
END;   
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

很奇怪,你不能USINGEXECUTE语句中使用。这是 postgres 的标准配置。

this来自手册页的确切信息:

命令字符串可以使用参数值,在命令中引用为 $1、$2 等。这些符号是指在 USING 子句中提供的值。这种方法通常比将数据值作为文本插入到命令字符串中更可取:它避免了将值转换为文本并返回的运行时开销,并且由于不需要引用或逃脱。

我已将查询修改为与手册中的查询相似 - 现在尝试。

于 2013-07-10T16:34:14.707 回答