Richiamare procedure o funzioni PostgreSQL da Query Builder di QGIS
Sto cercando di chiamare una procedura memorizzata o una funzione definita nel database PostgreSQL / PostGIS e di utilizzarla da QGIS Query Builder. Nessuno dei due funziona:
- la funzione restituisce una tabella che non può essere interpretata dal Query Builder
- la procedura, che restituisce una selezione, fallisce quando la chiamo usando l'
callistruzione
Entrambi funzionano bene in DataGrip e interrogano un tag da una tagcolonna di matrice di testo nella waypointstabella.
Ecco la funzione:
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; $$
Ecco la procedura che fallisce CALLnel Query Builder di QGIS:
create or replace procedure grw(T text)
LANGUAGE plpgsql
AS $$ BEGIN SELECT * FROM gis.gps.waypoints where tag @> STRING_TO_ARRAY(T, ','); end; $$
Ecco l'errore riportato da QGis quando eseguo call grw('iron')nel 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 lo chiamo senza CALL, non funziona neanche:
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.
Risposte
Tre cose:
A
PRODECUREè un'istruzione procedurale consapevole della transazione , introdotta in PG 11, per accogliere il controllo della transazione mancante in unFUNCTIONblocco normale .Tuttavia , a
PROCEDUREnon può restituire valori e nient'altro che chiamarlo direttamente con ( nient'altro ma )CALL <procedure>;non può funzionare. Si desidera utilizzare
PROCEDUREogni volta che si desidera eseguire istruzioni DDL sulle relazioni con il controllo delle transazioni , gestendo gli errori durante l'esecuzione in modo più elegante. Semanticamente, quello che stai cercando è un fileFUNCTIONLa finestra di dialogo Generatore di query consente di aggiungere rapidamente espressioni di filtro sull'origine dati.
Tuttavia , QGIS traduce questi filtri nella sintassi specifica del provider , il che significa che, in caso di un livello sorgente PostgreSQL / PostGIS, aggiungerà queste istruzioni a una query di base sotto forma di
SELECT * FROM "<schema>"."<table>" WHERE <FILTER>;dove
<FILTER>è l'espressione precisa inserita nel campo di dialogoIn ogni caso, i tuoi tentativi sono inutili (senza offesa) per il modo in cui intendi usarli:
- non ha senso filtrare una tabella per un tag per utilizzare le righe / valori restituiti come lo stesso filtro per la stessa tabella
- e se si desidera farlo, è necessario definire nuovamente un'espressione di filtro per utilizzare le righe / i valori restituiti
La soluzione più semplice sarebbe solo ( e solo ) entrare
'iron' = ANY(tag)
nel campo Espressione del generatore di query ; questo si traduce in
SELECT * FROM "gps"."waypoints" WHERE 'iron' = ANY(tag);
che è possibile utilizzare direttamente in SQL se necessario.