Trabajando Con Store Procedures PL/PGSQL en PostgreSQL

Está en la página 1de 9

Trabajando con Store Procedures PL/pgSQL en PostgreSQL

por Martn Mrquez <[email protected]>

Los lenguajes de procedimientos (procedural languages) han extendido la funcionalidad de las bases de
datos proporcionando al lenguaje SQL cierto flujo de control similar al de un lenguaje de
programacin.
Cada fabricante tiene su propia implementacin de un lenguaje de procedimiento basado en SQL, as
Microsoft SQL Server tiene Transact-SQL, Oracle tiene PL/SQL y as sucesivamente una lista de
bases de datos con su correspondiente lenguaje de procedimiento. En el caso de PostgreSQL se tienen
varios lenguajes que pueden usarse como lenguajes de procedimiento entre ellos tenemos a PL/Tcl,
PL/Perl, PL/Python,C y como opcin predeterminada PL/pgSQL.
Las ventajas de ejecutar funciones del lado del servidor o Store Procedures con PL/pgSQL son las
siguientes:
1. Extensibilidad: PL/pgsql es como un lenguaje de programacin incluye la asignacin y
evaluacin de variables y la posibilidad de hacer iteraciones y clculos ms complejos que con
SQL.
2. Seguridad: Ayuda a evitar ciertos ataques con SQL Injection ya que al utilizar parmetros evita
la construccin de comandos SQL utilizando la concatenacin de cadenas.
3. Rapidez: Son ejecutados ms rpidamente que las consultas SQL individuales ya que despus
de la primera ejecucin el plan de ejecucin se mantiene en memoria y el cdigo no tiene que
ser analizado ni optimizado nuevamente.
4. Programacin modular: similar a los procedimientos y funciones en los lenguajes de
programacin, lo que evita que se tengan planas de sentencias SQL.
5. Reutilizacin: de cdigo una funcin puede ejecutarse dentro de distintos Store Procedures.
6. Rendimiento: un Store Procedure puede contener decenas de sentencias SQL que son
ejecutadas como una sola unidad de golpe, a diferencia de las sentencias SQL individuales
donde hay que esperar a que cada una sea procesada.
Mediante los siguientes ejemplos mostraremos el uso de Store Procedures utilizando PL/pgSQL.
Creamos una base de datos de ejemplo llamada Catalogs con el siguiente comando desde el Shell.
$ createdb Catalogs

Fig 1. Creando la base de datos de ejemplo

Revisamos los lenguajes de procedimiento instalados en la base de datos, revisamos que PL/pgSQL se
encuentre instalado con el siguiente comando.
$ createlang -l Catalogs

Fig 2. Revisando la instalacin del lenguaje PLSQL

Si no se encuentra, entonces ejecutamos el siguiente comando para instalarlo, esto siempre como
administrador del servidor:
$ createlang U postgres plpgsql Catalogs

Si est instalado entonces abrimos un editor de texto y creamos un archivo llamado catalogs.sql donde
escribiremos los comandos para crear las tablas de ejemplo y los Store Procedures para administrar los
registros de cada una de las tablas.
Para la creacin de las tablas escribimos lo siguiente:
CREATE TABLE Countries(
idcountry char(3) NOT NULL PRIMARY KEY
,name varchar(250) NOT NULL
,created timestamp DEFAULT NOW() NOT NULL
);
CREATE TABLE States(
idstate serial NOT NULL PRIMARY KEY
,name varchar(250) NOT NULL
,idcountry varchar(3) NOT NULL REFERENCES Countries(idcountry)
,created timestamp DEFAULT NOW() NOT NULL
);
CREATE TABLE Cities(
idcity serial NOT NULL PRIMARY KEY
,name varchar(250) NOT NULL
,idstate int NOT NULL REFERENCES States(idstate)
,created timestamp DEFAULT NOW() NOT NULL
);

En acuerdo con la llave fornea definida en cada tabla, debe existir un pas para poder crear un estado,
as mismo debe de existir un estado para poder crear una ciudad, entonces creamos unos registros en la
tabla pases
INSERT
INSERT
INSERT
INSERT

INTO
INTO
INTO
INTO

Countries(idcountry,name)VALUES('arg','argentina');
Countries(idcountry,name)VALUES('bra','brasil');
Countries(idcountry,name)VALUES('ury','uruguay');
Countries(idcountry,name)VALUES('mex','mxico');

Fig 3. Insertando los registros en la tabla

Supongamos que estas tablas van a utilizarse en un sistema donde sea obligatorio que los nombres de
pas, estado y ciudad, se almacenen teniendo la primera letra mayscula o en notacin Camel Case,(en
este caso los pases quedaron guardados con letras minsculas de manera intencional, con el fin de
mostrar un Store Procedure).
Creamos entonces una funcin para aplicar esta regla a los datos de la tabla countries.
La funcin se define con el siguiente cdigo:
CREATE FUNCTION UpperCamelCase(varchar) RETURNS varchar AS
'DECLARE
res varchar;
BEGIN
SELECT INTO res UPPER(SUBSTRING($1,1,1)) || LOWER(SUBSTRING($1,2));
return res;
END;'
LANGUAGE 'plpgsql';

Lo aplicamos de la siguiente manera para actualizar los registros.

Fig 4. Actualizando los registros utilizando la funcin UpperCamelCase

Una vez creada en el servidor se encuentra disponible para cualquier transformacin que queramos
aplicar sobre cualquier cadena.

Fig 5. Ejecutando la funcin UpperCamelCase

Ahora escribiremos las funciones para insertar registros en cada una de las tablas.
CREATE FUNCTION InsertState(varchar,varchar) RETURNS int AS
'DECLARE
regs record;
res numeric;
BEGIN
SELECT INTO regs count(name) FROM States WHERE name = UpperCamelCase($1);
IF regs.count = 0
THEN
INSERT INTO States(name,idcountry)VALUES(UpperCamelCase($1),$2);
SELECT INTO res idstate FROM States WHERE name = UpperCamelCase($1);
RETURN res;
END IF;
IF regs.count > 0
THEN
SELECT INTO res idstate FROM States WHERE name = UpperCamelCase($1);
RETURN res;
END IF;
END;
' LANGUAGE 'plpgsql';
CREATE FUNCTION InsertCity (varchar,numeric) RETURNS int AS
'DECLARE
regs record;
res numeric;
BEGIN
SELECT INTO regs count(name) FROM Cities WHERE name = UpperCamelCase($1);

IF regs.count = 0
THEN
INSERT INTO Cities(name,idstate)VALUES(UpperCamelCase($1),$2);
SELECT INTO res idcity FROM Cities WHERE name = UpperCamelCase($1);
RETURN res;
END IF;
IF regs.count > 0
THEN
SELECT INTO res idcity FROM Cities WHERE name = UpperCamelCase($1);
RETURN res;
END IF;
END;
' LANGUAGE 'plpgsql';

Bsicamente la estructura de un Store Procedure es la siguiente:


CREATE FUNCTION [nombre de la funcin] ([parmetros separados por comas]) RETURNS
[el tipo de dato que regresa] AS
'DECLARE aqu se definen las variables que se usarn.
BEGIN indica el inicio de la funcin.
SELECT INTO este comando permite que los resultados de las consultas sean asignados
a variables.
(no debe de confundirse con SELECT [columnas] INTO)
RETURN Sale de la funcin y regresa el tipo de dato que se declaro despus de la
palabra RETURNS del CREATE FUNCTION
END indica el fin de la funcin
' LANGUAGE indica con que lenguaje esta escrita la funcin, puede ser un lenguaje
de procedimiento
(plpgsql) o de consulta (SQL).

Vemos que en cada Store Procedure, reutiliza la funcin UpperCamelCase(varchar) que habamos
previamente creado.
Esto porque un Store Procedure puede llamar a otro Store Procedure que se encuentre disponible.
En las siguientes imgenes los resultados de la ejecucin de cada Store Procedure.

Fig 6. Ejecuccin del procedimiento InsertState

Fig 7. Ejecuccin del procedimiento InsertCity

Fig 8. Comprobando la aplicacin de los procedimientos en los datos

Descarga el cdigo fuente para PostgreSQL


Este documento est protegido bajo la licencia de documentacin libre Free Documentacion License del
Proyecto GNU, para consulta ver el sitio http://www.gnu.org/licenses/fdl.txt , toda persona que lo desee est
autorizada a usar, copiar y modificar este documento segn los puntos establecidos en la Licencia FDL

También podría gustarte