diumenge, 23 de gener del 2011

Stored Procedures amb PostgreSQL

A l'hora de desenvolupar aplicacions web, una aproximació possible és la de mantenir la lògica de negoci implementada al servidor de base de dades en forma de procediments emmagatzemats, o stored procedures, o dit d'una altre forma:  hi ha vida més enllà d'Hibernate.

La utilització de procediments emmagatzemats pot aportar beneficis evidents: per exemple, ens podem estalviar un munt de transport d'informació entre el servidor de base de dades i el servidor d'aplicacions. També té problemes. Potser el més evident és que la base de dades es carrega amb el cost de processar la lògica, ara bé, per a una quantitat molt gran de processos de negoci, no hi han grans càlculs a realitzar i el cost es redueix, precisament a moure dades entre taules i càlculs simples.

En tot cas, és una opció a tenir en compte.

Els servidors de bases de dades MySQL, PostgreSQL o FireBird, potser els  més populars a Linux, permeten implementar  procediments emmagatzemats.

En aquest post faré un exercici senzill amb procediments emmagatzemats a PostgreSQL.

El cas de PostgreSQL és una mica especial: El llenguatge de procediments, el PL/PGSQL, no està disponible d'entrada. Cal "Crear-lo". O bé amb una instrucció CREATE LANGUAGE, o bé amb la utilitat createlang. Aquesta és l'opció que he triat.


albert@atenea:~$ createlang --dbname=proves --host=localhost --username=postgres --password PLPGSQL
Password: elmeupassword

La instrucció anterior "activa" el PL/PGSQL a la base de dades 'proves' que tinc al meu localhost. l'opció --password força que es demani el password de l'usuari.


Aleshores faig servir el pgAdmin III com a entorn d'administració  i obro una finestra de SQL

 Ala finestra hi escric una funció simple que suma dos números

-- Function: provasuma(integer, integer)
-- DROP FUNCTION provasuma(integer, integer);

CREATE OR REPLACE FUNCTION provasuma(val1 integer, val2 integer)
  RETURNS integer AS
$$
BEGIN
    /*
    Això és un comentari de més d'una línia
    */
    RAISE NOTICE 'suma %  i  %', Val1, Val2;
    RETURN Val1 + Val2;
END; 
$$
LANGUAGE 'plpgsql'

Coses interessants:
Només podem crear funcions.
Comentaris d'una línia amb --
Comentaris de més d'una línia amb /* ... */
El cos de la funció queda determinat per les marques $$
La depuració és un punt fluix i, en principi, fent servir el pgAdmin, o el psql, no ens en queda altre que depurar al vell estil amb printf, en aquest cas amb raise.
La sintaxi és molt similar a la de PL/SQL.

Cal indicar el llenguatge. Per defecte, PostgreSQL admet també les opcions plpgsql, internal,  C i SQL per al llenguatges. Ara bé, "internal" només serveix per a fer alies nous de les funcions ja disponibles, "C" és per enllaçar dinàmicament llibreries de funcions escrites i compilades en aquest llenguatge, "SQL" sí que permet fer funcions però només d'instruccions SQL separades per ";", finalment, "plpgsql" ens permet fer funcions amb estructures de control, llaços, iteracions...

Com a mostra, la senzilla funció que he escrit abans , també l'hauria pogut escriure com una funció del tipus "SQL":


-- Function: provasuma2(integer, integer)
-- DROP FUNCTION provasuma2(integer, integer);
CREATE OR REPLACE FUNCTION provasuma2(integer, integer)
  RETURNS integer ASemès per  'select $1 + $2'
  LANGUAGE 'SQL'


Les funcions  anteriors les puc invocar des de psql o pgAdmin


proves=# select provasuma(23,546);
NOTICE:  suma 23  i  546
 provasuma 
-----------
       569
(1 row)

O la segona d'elles:

proves=# select provasuma2(23,546);
 provasuma2 
------------
        569
(1 row)


on no apareix el missatge del RAISE.

Finalment, el llenguatge es descriu en aquest enllaç. El més destacable és que, sintàcticament, el PL/pgSQL i el PL/SQL d'Oracle són força similars, de forma que els programadors d'aquest  llenguatge del gegant de les bases de dades en tindran molt de guanyat. Més encara quan el PL/pgSQL vindria a ser un subconjunt del PL/SQL.

Per tal de facilitar la migració de codi de PL/SQL d'Oracle a PL/pgSQL de PostgreSQL en aquest altre enllaç trobem diferències entre tots dos i consells per a la  migració.

Cap comentari:

Publica un comentari a l'entrada