2015-11-12 8 views
0

Мне нужно преобразовать из 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 

Это не передаёт имя таблицы в качестве аргумента

EDIT 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

+0

Вы, возможно, придется использовать PL/PgSQL и динамическую конструкцию SQL. – dezso

+0

Я очень n00b в postgres, как бы я это сделал? – tvieira

ответ

1

AS @dezso отметил, что в этом случае вам понадобится динамический SQL.

Dynamic SQL с EXECUTE

Итак, вы на правильном пути; образуя динамический оператор SQL с помощью PL/PgSQL, но вам просто нужно штрихи:

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, я попытался исправить указанные ниже проблемы.

EDIT:

Несколько правок здесь, надеюсь, одно решение будет решить проблему. Кроме того, пожалуйста, извините любые синтаксические ошибки в моих предыдущих & текущих решениях; У меня нет времени проверять их прямо сейчас. :(

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; 
+0

Я обновил вопрос, я попробовал это решение, и у меня есть «ERROR: не могу использовать RETURN QUERY в функции, отличной от SETOF» – tvieira

+0

Итак, есть два возможных решения. Я попытаюсь посмотреть, смогу ли я сделать соответствующие изменения ... – Chris

+0

Yup it сделал трюк! Потрясающие – tvieira

Смежные вопросы