将 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;
我必须将经纬度转换为 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;