Chamando procedimentos ou funções PostgreSQL do Query Builder do QGIS
Estou tentando chamar um procedimento armazenado ou função definida no banco de dados PostgreSQL / PostGIS e usá-lo a partir do QGIS Query Builder. Nenhum trabalho:
- a função retorna uma tabela que não pode ser interpretada pelo Query Builder
- o procedimento, que retorna uma seleção, falha quando eu o chamo usando a
callinstrução
Ambos funcionam bem no DataGrip e consultam uma tag de uma tagcoluna de matriz de texto na waypointstabela.
Aqui está a função:
create or replace function gwd(t text)
RETURNS TABLE (f_ogc_fid int, f_name text)
LANGUAGE plpgsql
AS $$ BEGIN return query SELECT ogc_fid,name::text FROM gis.gps.waypoints where tag @> STRING_TO_ARRAY(t, ','); end; $$
Aqui está o procedimento que falha no CALLQuery Builder do QGIS:
create or replace procedure grw(T text)
LANGUAGE plpgsql
AS $$ BEGIN SELECT * FROM gis.gps.waypoints where tag @> STRING_TO_ARRAY(T, ','); end; $$
Aqui está o erro relatado pelo QGis quando executo call grw('iron')no Query Builder:
An error occurred when executing the query.
The data provider said:
ERROR: syntax error at or near "grw"
LINE 1: SELECT * FROM "gps"."waypoints" WHERE call grw('iron') LIMIT...
Quando eu ligo sem o CALL, também não funciona:
An error occurred when executing the query.
The data provider said:
ERROR: grw(unknown) is a procedure
LINE 1: SELECT * FROM "gps"."waypoints" WHERE grw('iron') LIMIT 0
HINT: To call a procedure, use CALL.
Respostas
Três coisas:
A
PRODECUREé uma instrução de procedimento ciente de transação , introduzida no PG 11, para acomodar o controle de transação ausente em umFUNCTIONbloco normal .No entanto , a
PROCEDUREnão pode retornar valores e qualquer outra coisa senão chamá-lo diretamente com ( nada além de )CALL <procedure>;Não pode trabalhar. Você deseja usar um
PROCEDUREsempre que desejar executar instruções DDL em suas relações com o controle de transação , enquanto lida com erros durante a execução de forma mais elegante. Semanticamente, o que você está procurando é umFUNCTIONA caixa de diálogo Construtor de consultas permite adicionar rapidamente expressões de filtro na fonte de dados.
No entanto , o QGIS traduz esses filtros em sintaxe específica do provedor , o que significa que, no caso de uma camada de origem PostgreSQL / PostGIS, ele adicionará essas instruções a uma consulta de base na forma de
SELECT * FROM "<schema>"."<table>" WHERE <FILTER>;onde
<FILTER>é a expressão precisa inserida no campo de diálogoDe qualquer forma, suas tentativas são inúteis (sem ofensa) para a maneira como você pretende usá-las:
- não faz sentido filtrar uma tabela por uma tag para usar as linhas / valores retornados como o mesmo filtro para a mesma tabela
- e se você quiser fazer isso, precisará definir novamente uma expressão de filtro para usar as linhas / valores retornados
A solução mais simples seria apenas ( e apenas ) inserir
'iron' = ANY(tag)
no campo Expressão do construtor de consulta ; isso se traduz em
SELECT * FROM "gps"."waypoints" WHERE 'iron' = ANY(tag);
que você pode usar no SQL diretamente, se necessário.