Non c'è niente di sbagliato in una funzione plpgsql per qualcosa di un po' più complesso. L'unica situazione in cui le prestazioni possono risentirne è quando una funzione plpgsql è nidificata, perché il pianificatore di query non può ottimizzare ulteriormente il codice contenuto nel contesto della query esterna, il che potrebbe rallentarla o meno.
Maggiori dettagli in questo seguito. risposta:
- Differenza tra linguaggio sql e linguaggio plpgsql nelle funzioni PostgreSQL
Nel caso in questione è molto più semplice di molti CASE
clausole in una query:
CREATE OR REPLACE FUNCTION get_stuff(_param text, _orderby text, _limit int)
RETURNS SETOF stuff AS
$func$
BEGIN
RETURN QUERY EXECUTE '
SELECT *
FROM stuff
WHERE col = $1
ORDER BY ' || quote_ident(_orderby) || ' ASC
LIMIT $2'
USING _param, _limit;
END
$func$ LANGUAGE plpgsql;
Chiama:
SELECT * FROM get_stuff('hello', 'col2', 100);
Note
Usa RETURN QUERY EXECUTE
per restituire i risultati della query in una volta sola.
Usa quote_ident()
per gli identificatori per la protezione da SQLi.
O format()
per qualcosa di più complesso. Vedi:
- Nome tabella come parametro di funzione PostgreSQL
Passa i valori dei parametri con USING
clausola per evitare ancora una volta casting, citazioni e SQLi.
Fare attenzione a non creare conflitti di denominazione tra parametri e nomi di colonna. Ho anteposto i nomi dei parametri con un trattino basso (_
) nell'esempio. Solo una mia preferenza personale.
La tua seconda funzione dopo la modifica non può funzionare, perché restituisci solo parent
mentre il tipo restituito è dichiarato SETOF stuff
. Puoi dichiarare qualsiasi tipo restituito che ti piace, ma i valori restituiti effettivi devono corrispondere alla dichiarazione. Potresti voler usare RETURNS TABLE
per quello.