将 table 作为参数传递

Passing the table as a parameter

我必须将经纬度转换为 geom 才能使用 PostGIS。我的问题是,我有来自不同位置的各种 table,我想将 table 作为参数传递给函数。我正在尝试这个:

CREATE or REPLACE FUNCTION convert_from_lon_lat(float,float,character varying)      
RETURNS  integer AS $$
select id from  as vertices 
order by  vertices.geom <-> ST_SetSrid(ST_MakePoint(,),4326) LIMIT 1;
$$ LANGUAGE SQL;

但我收到语法错误。

编辑 1:

所以我把之前的代码改成这样:

CREATE or REPLACE FUNCTION convert_from_lon_lat(long float, lat float, _table character varying) RETURNS  integer AS $$
BEGIN
EXECUTE('select id from _table as vertices order by  vertices.geom <-> ST_SetSrid(ST_MakePoint(long,lat),4326) LIMIT 1;');
END;
$$ LANGUAGE plpgsql;

它创建没有任何问题,但是当我调用它时`convert_from_lon_lat(long1, long2, my_table)

我收到错误:

ERROR:  relation "_table" does not exist

它没有将 table 名称作为参数传递

编辑 2:

CREATE or REPLACE FUNCTION convert_from_lon_lat(long float, lat float, tbl character varying) RETURNS  integer AS $func$
BEGIN
EXECUTE format('select id from %s order by  %s.the_geom <-> ST_SetSrid(ST_MakePoint('|| long || ','|| lat ||'),4326) LIMIT 1;', tbl, tbl);
END;
$func$ LANGUAGE plpgsql;

现在,当我调用该函数时,我得到一个`错误:控制到达函数末尾 RETURN``

我试过 RETURN QUERY EXECUTE format('... 但我得到 ERROR: cannot use RETURN QUERY in a non-SETOF function

如@dezso 所述,在这种情况下你需要动态 SQL。

动态 SQL 和 EXECUTE

那么,您的方向是正确的;使用 PL/pgSQL 形成动态 SQL 语句,但您只需要最后的润色:

CREATE or REPLACE FUNCTION convert_from_lon_lat(long float, lat float, _table text) 
RETURNS integer AS $$
BEGIN
RETURN QUERY EXECUTE format('SELECT id FROM %I AS vertices 
  ORDER BY vertices.geom <->ST_SetSrid(ST_MakePoint(long,lat),4326) LIMIT 1;',_table);
END
$$ LANGUAGE plpgsql;

我相信这应该可以解决您的问题。

注意:我们发现上述解决方案和使用 SETOF 存在错误,我已尝试更正以下问题。

编辑:

此处进行了一些编辑,希望一个解决方案可以解决您的问题。另外,请原谅我以前和当前解决方案中的任何语法错误;我现在没有时间测试它们。 :(

1) 你可以尝试 return 一个 SETOF 整数,当然你知道你只会 return 那个.在这种情况下,您的 return 类型将是一个包含整数的单列行。

CREATE or REPLACE FUNCTION convert_from_lon_lat(long float, lat float, _table text) 
RETURNS SETOF integer AS $$
BEGIN
RETURN QUERY EXECUTE format('SELECT id FROM %I AS vertices 
  ORDER BY vertices.geom <->ST_SetSrid(ST_MakePoint(long,lat),4326) LIMIT 1;',_table);
END
$$ LANGUAGE plpgsql;

然后调用为:

SELECT * FROM convert_from_lon_lat(...);

2)具体return一个整数,我想你可以试试这个:

CREATE or REPLACE FUNCTION convert_from_lon_lat(long float, lat float, _table text) 
RETURNS integer AS $$

DECLARE
return_id integer;

BEGIN
EXECUTE format('SELECT id FROM %I AS vertices 
  ORDER BY vertices.geom <->ST_SetSrid(ST_MakePoint(long,lat),4326) LIMIT 1;',_table)
  INTO return_id;

RETURN return_id;
END
$$ LANGUAGE plpgsql;