将表作为参数传递

时间:2015-11-12 12:55:53

标签: postgresql plpgsql dynamic-sql postgresql-9.3

我必须从lat和long转换为geom才能使用PostGIS。我的问题,我有来自不同位置的各种表,我想将表作为参数传递给函数。我试过这个:

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

但是我收到语法错误。

EDIT1:

所以我将之前的代码更改为:

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

它没有将表名作为参数传递

编辑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

1 个答案:

答案 0 :(得分:1)

AS @dezso提到,在这种情况下你需要动态SQL。

EXECUTE

的动态SQL

所以,你正走在正确的轨道上;使用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)您可以尝试返回SETOF个整数,因为您知道当然只返回一个整数。在这种情况下,您的返回类型将是包含整数的单个一列行。

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)要专门返回一个整数,我想你可以试试这个:

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;