Mondi su mondi, sistemi di sistemi.

PostgreSQL: cursori e query dinamiche

Con PostgreSQL, vista l’abbondanza di lin­guaggi che pos­sono essere usati per creare le fun­zioni, è spesso molto con­ve­niente spo­stare molta di quella logica che soli­ta­mente gira nell’application ser­ver diret­ta­mente nel database.

Tuttavia, uno dei limiti nell’usare le pro­ce­dure in PostgreSQL è che i vin­coli sui data­type resti­tuiti dalle fun­zioni sono piut­to­sto rigidi. In pra­tica, il sistema deve sapere al momento della com­pi­la­zione tutti i tipi di valori restituiti. Perciò, o dichia­riamo i para­me­tri OUT e nella clau­sola di return usiamo record, oppure, sem­pre nella clau­sola di return usiamo una tabella/view/tipo com­po­sito già pre­sente nel cata­logo. #

Di solito pre­fe­ri­sco la secondo solu­zione per­ché in que­sto modo si crea una dipen­denza espli­cita fra la fun­zione e la tabella/view/tipo com­po­sito restituito.

Questo però vuol dire che non pos­siamo scri­vere una fun­zione gene­rica che possa essere usata su più tabelle. Tuttavia, con i cur­sori pos­siamo otte­nere pra­ti­ca­mente la stessa cosa.

Ad es, basta una fun­zione come questa:

CREATE OR REPLACE FUNCTION get(IN table_name text) RETURNS refcursor AS $$
BEGIN
    OPEN c FOR EXECUTE 'SELECT * FROM ' || quote_ident($1);
    RETURN c;
END;
$$ language plpgsql;

 

per poi:

BEGIN;
SELECT get('table');
FETCH ALL FROM result;
COMMIT;

 

L’unico svan­tag­gio è il dover aprire sem­pre una tran­sa­zione ma mi sem­bra un prezzo ragionevole.

Per proseguire

Commenti e trackback sono disabilitati.