OBJETIVO

Muchos de los motores de bases de datos, están incursionando en nuevas tecnologías, aplicando las nuevas técnicas para el tratamiento de información.

Existe una marcada tendencia a responsabilizar la base de datos en los procesos de ejecución de procesos, para quitar carga a los clientes que como es de imaginar poseen menos recursos. En el paradigma Cliente/Servidor esta característica es fundamental, ya que el Cliente hace peticiones al Servidor, el cual resuelve la instrucción y retorna al Cliente los datos solicitados.

Interbase posee una forma de almacenar código en la base de datos, que permite ejecutar una serie de instrucciones que corren en el motor; esta característica permite realizar operaciones que antes debían ser implementadas por el cliente, mediante el lenguaje utilizado.

Estos procedimientos se denominan Stored Procedures (Procedimientos almacenados), y pueden ser escritos en el Lenguaje de Triggers y Procedimientos. Otra forma de código que puede ser almacenada, se realiza mediante procesos denominados Triggers.

En esta unidad, es objetivo que el lector conozca el funcionamiento de los Procedimientos almacenados, su utilidad, y como programarlos. Comprenda la sintaxis del Lenguaje de Procedimientos y pueda utilizarlos junto con los Triggers para realizar programas potentes y de gran rendimiento.

 

PANORÁMICA

Primeramente se iniciará el estudio de los procedimientos almacenados; el concepto, como programarlos con el lenguaje de Procedimientos. Se comentarán algunas características particulares de ellos, así como su ejecución y manipulación.

Se presentarán ejemplos de como establecer parámetros de entrada y salida, como se debe programar un procedimiento SELECT, el cual devuelve conjuntos de datos; y cual es la forma o característica de una procedimiento de ejecución.

En la segunda parte, se tratará en concepto de disparadores (Triggers), su filosofía de ejecución y manipulación, las características propias de cada tipo de Trigger, y como manipularlos efectivamente.

Por último se indicará como programar las excepciones y manipulación de errores en Interbase, utilizando la instrucción WHEN.

¿QUE ES UN PROCEDIMIENTO ALMACENADO?

Un procedimiento embebido o almacenado, son procedimientos escritos en lenguaje de Trigger o procedimiento, que es almacenado en la base de datos como parte de los METADATOS.

Una vez creados, pueden ser llamados de cualquier aplicación, o ser sustituido en una cláusula SELECT como una tabla o vista.

Los procedimientos pueden recibir parámetros de entrada y retornar valores a las aplicaciones.

Muchos de los procesos que son implementados utilizando el mismo lenguaje en el que se ha desarrollado la aplicación cliente, puede ser sustituidos por procesos implementados a través de procedimientos almacenados; esto tienen un ingrediente muy importante, ya que el programador puede estructurar mejor el código, y le permitirá tener cierta agilidad y mejora en el tiempo que invierte, separando los procesos inherentes a la interfaz, con los procesos de manipulación de información.

Un comentario muy importante al respecto de los procedimientos almacenados, es la gran similitud o al menos lo que parece que se persigue, con las bases de datos orientadas a objetos; no quiero decir que el hecho de poder programar procedimientos almacenados implique tener una base de datos Orientada a Objetos, sino que la tendencia de los motores de bases de datos, es por ese rumbo.

VENTAJAS DE LOS PROCEDIMIENTOS ALMACENADOS

Podemos encontrar muchas ventajas al utilizar procedimientos almacenados, y dependiendo del proceso que el usuario decida que deba de ser implementado puede llegar a mejorar el rendimiento de una aplicación.

Aquí mencionamos a nivel general algunas de las ventajas que pueden ser acreditadas a los procedimientos almacenados (Stored Procedures).
 
 

 

CUANDO DEBEN USARSE PROCEDIMIENTOS ALMACENADOS

La utilización de los procedimientos almacenados esta en función de la aplicación que se este desarrollando; sin embargo, se pueden establecer una orientación que permita al programador intuir donde puede ser útil un procedimiento y donde resulta inoficioso.

Los siguientes casos generales pueden ayudar mucho a un programador en la definición de la estructura de la base de datos en cuanto a procedimientos almacenados se refiere :

 

CREACIÓN DE PROCEDIMIENTOS ALMACENADOS

Los procedimientos son creados en Interbase por medio de la instrucción CREATE PROCEDURE. Esta instrucción permite crear diferentes tipos de procedimientos que serán almacenados en la base de datos.

Se pueden crear dos tipos de procedimientos almacenados.

Procedimientos SELECT

Son procedimientos que pueden ser utilizados en una sentencia SELECT a cambio de una tabla o una vista. Un procedimiento de este tipo puede arrojar más de un valor como parámetro de salida, o un mensaje de error.
 

Procedimientos EJECUTABLES

Son procedimientos que un aplicación puede llamar directamente con la sentencia EXECUTE PROCEDURE . Puede opcionalmente retornar valores.

Ambos tipos de procedimientos son creados de la misma forma y tienen la misma sintaxis esencialmente, la diferencia esta en la forma como ha sido escrito y la forma como se utilizará.

 

ESTRUCTURA DE UN PROCEDIMIENTO ALMACENADO

Un procedimiento almacenado está compuesto de un encabezado y un cuerpo.
 

ENCABEZADO

El encabezado contiene:

 

CUERPO DEL PROCEDIMIENTO

El cuerpo del procedimiento contiene:

 

SINTAXIS PARA LA CREACION DEL PROCEDIMIENTO

Para poder entender de una manera más práctica lo anteriormente mencionado, es importante observar la sintaxis para la creación de un procedimiento mediante la orden CREATE PROCEDURE:
 

CREATE PROCEDURE nombre [ (parámetro Tipo_de_dato [, parámetro Tipo_de_dato …])]

[RETURNS ( parámetro Tipo_de_dato [, parámetro Tipo_de_dato …])]

AS

<Cuerpo del procedimiento>;

<Cuerpo del procedimiento =[ <Lista de declaración de variables> ]<bloque>

< Lista de declaración de variables > =

DECLARE VARIABLE variable Tipo_de_dato;

[DECLARE VARIABLE variable Tipo_de_dato; …]

<bloque> = BEGIN

<Sentencias>

[ <Sentencias> …]

END

<Sentencias> = { <bloque | Sentencia>;}

 

EJEMPLOS

Como puede observarse, la sintaxis es muy sencilla y es fácil de aprender por su simplicidad en las palabras reservadas. En el Cuadro 1 se resumen la aplicación de cada una de los elementos de la sintaxis. Los siguientes ejemplos aclaran mejor la sintaxis inicial.
   

1.

CREATE PROCEDURE almacen_alta (ALMACEN CHAR(3))
AS
DECLARE VARIABLE articulo CHAR(10) ;
DECLARE VARIABLE ArtTmp CHAR(10) ;
BEGIN
......

END

Cuadro 1.
  

Nombre

Nombre del procedimiento

Parámetro< Tipo_de_dato

Parámetros de entrada que el programa que lo llama utiliza para pasar valores al procedimiento.

RETURNS

Parámetro

< Tipo_de_dato

Parámetros que el procedimiento utiliza para retornar valores a los programas que lo llaman. El procedimiento retorna los valores de salida cuando se utiliza SUSPEND en el cuerpo del procedimiento.

AS

Palabra que separa la cabecera del procedimiento del cuerpo.

DECLARE VARIABLE

Variable < Tipo_de_dato

Declara las variables locales utilizadas solamente en el procedimiento. Cada declaración debe ser declarada con DECLARE VARIABLE y seguida por un punto y coma (;).

Variable : Nombre de la variable local. Data type : tipo de dato de la variable local.

Sentencia

Una sentencia en lenguaje de Trigger y procedimiento.

 

En este ejemplo se ilustra la creación de un procedimiento que acepta un parámetro entrada ALMACEN de tipo CHAR(3), y la declaración de dos variables Articulo y ArtTmp.
 

2.

CREATE PROCEDURE con_dame_nivel (CUENTA VARCHAR(15))
RETURNS (NIVEL SMALLINT)
AS
BEGIN
.......

END

La anterior instrucción crear un procedimiento CON_DAME_NIVEL que acepta como parámetro de entrada CUENTA de tipo VARCHAR(15) y retorna una variable NIVEL de tipo SMALLINT.
 

3.

CREATE PROCEDURE duplicados
RETURNS (Z CHAR(4))
AS

BEGIN

....

END

Este ejemplo permite ilustrar que los parámetros de entrada son opcionales. La instrucción anterior crear un procedimiento DUPLICADOS que no tiene parámetros de entrada, pero que retorna una variable Z de tipo CHAR(4).

 

4.

CREATE PROCEDURE log_entradas_entrada (MAQUINA VARCHAR(31), NOMBRE VARCHAR(31))
RETURNS

(ENTRADA INTEGER, USUARIO INTEGER, FECHA DATE, EJERCICIO CHAR(4))
AS
BEGIN

....

END

Este ejemplo permite ilustra la forma de colocar varios parámetros de salida. La instrucción crea un procedimiento LOG_ENTRADAS_ENTRADA que acepta dos parámetros de entrada MAQUINA y NOMBRE de tipo VARCHAR(31) cada una, y retorna cuatro variables de salida, ENTRADA y USUARIO de tipo INTEGER, FECHA de tipo DATE y ejercicio de tipo CHAR(4).

En las próximas secciones se estudiará mas a fondo cada una de las sentencias utilizadas dentro del cuerpo del procedimiento. Como se puede notar, los anteriores ejemplos únicamente ilustran la utilización de parámetros, tanto de entrada como de salida y la declaración de variables, que se utilizarán dentro del cuerpo del procedimiento.

Los anteriores ejemplo ilustran los posibles casos en la utilización de parámetros, eso es para dejar claro cualquier posibilidad y el lector tenga un ejemplo de cada uno. En el ejemplo de curso, se encuentran todos estos procedimientos, así como los que se utilizarán más adelante.
 

EJECUTANDO PROCEDIMIENTOS ALMACENADOS

Ya se ha estudiado la cabecera y la forma de declaración de parámetros de entrada y salida en la sección anterior. Ahora se estudiará las posibilidades para llamar procedimientos y la forma de ejecutarlos.
 

SINTAXIS

Para llamar un procedimiento se utiliza la instrucción SQL EXECUTE PROCEDURE, que tiene la siguiente sintaxis:

Desde SQL la sintaxis es :

EXECUTE PROCEDURE [TRANSACTION Transacción] Nombre

[: Parámetro [[INDICATOR]: Indicador]]

[, : Parámetro [[INDICATOR]: Indicador] …]

[RETURNING_VALUES

: Parámetro [[INDICATOR]: Indicador]

[, : Parámetro [[INDICATOR]: Indicador] …]];
 
 

En el cuadro 2 se describen cada una de las claúsulas anteriores.

Cuadro 2
 

ARGUMENTO

DESCRIPCION

TRANSACTION

Transacción

Específica la transacción bajo la cual, la ejecución ocurre

Nombre

Nombre de un procedimiento existente en la base de datos.

Parámetro

Parámetros de entrada y salida que pueden ser una variable del lenguaje host o constante

RETURNING_VALUES: parámetro

Variable Host que toma los valores de una parámetro de salida.

[INDICATOR] : Indicador

Variable host para indicar NULL o valores desconocidos.

Desde DSQL la sintaxis es :

EXECUTE PROCEDURE Nombre [ parámetro [,parámetro …]]

[RETURNING_VALUES parámetro [,parámetro …]]

Desde ISQL

EXECUTE PROCEDURE Nombre [parámetro [,parámetro …]]

En ISQL no es necesario anotar parámetros de salida, ya que automáticamente retorna valores de salida.
 

EXECUTE PROCEDURE llama a un procedimiento definido en la base de datos. Si el procedimiento requiere parámetros de entrada, deben de ser suministrados a través de variables del lenguaje host o como constantes. SI el procedimiento requiere parámetros de salida, deben de suministrarse en la claúsula RETURNING_VALUES por medio de variables host.
 

EJEMPLOS

Los siguientes ejemplos ilustran las llamadas a procedimientos almacenados.

 

1.

EXECUTE PROCEDURE escandallo_controla( :M, :HIJO);

Se puede observar en este ejemplo el llamado al procedimiento escandallo_controla, el cual no retorna valores y utiliza dos parámetros de entrada.

Este procedimiento es llamado desde otro procedimiento, es por esa razón que las variables tienen los dos puntos (:), eso se explicará más adelante.
 

2.

EXECUTE PROCEDURE escandallo_ajusta_articulo (:ARTICULO, :COSTO)
RETURNING_VALUES :COSTE ;

En este caso el procedimiento escandallo_ajusta_artículo es ejecutado enviando dos parámetros :artículo y :costo y retorna en la variable :coste un parámetro de salida.

 

3.

En isql se puede ejecutar el procedimiento anterior, para ello no es necesario anotar valores de retorno, ya que automáticamente los desplegaría. La razón es muy obvia, no hay forma de declarar variables host en isql.

La instrucción se ejecutaría de la siguiente manera:

EXECUTE PROCEDURE escandallo_ajusta_articulo (10, 1000)

La instrucción EXECUTE PROCEDURE no se utiliza para ejecutar los procedimientos SELECT, es utilizada para llamar los procedimientos.

 

Para ejecutar un procedimiento SELECT, se utiliza en lugar de una tabla o vista, y se suplen los parámetros delimitados por comas (,). Observar el siguiente ejemplo :
 

1.

SELECT producto FROM Obtener_Producto_costo(:Valor)

ORDER BY Producto;

El resultado de la instrucción SELECT anterior en el resultado de la ejecución del procedimiento Obtener_producto_costo, y retorna el parámetro de salida en Producto.

Un procedimiento Select, puede ser utilizado en cualquier parte donde una tabla o vista se puede desplegar. La única diferencia, es que hay que suplir los valores de entrada al procedimiento.
 

MODIFICANDO Y ELIMINANDO PROCEDIMIENTOS ALMACENADOS
 

MODIFICACIÓN DE PROCEDIMIENTOS. ALTER PROCEDURE

Para modificar un procedimiento se utiliza ALTER PROCEDURE, esta sentencia cambia la definición de un procedimiento almacenado sin afectar sus dependencias.

La sintaxis de ALTER PROCEDURE es similar a la de CREATE PROCEDURE.

ALTER PROCEDURE nombre

[( variable Tipo_de_dato [, variable Tipo_de_dato …])]

[RETURNS ( variable Tipo_de_dato [, variable Tipo_de_dato …])]

AS

<Cuerpo del procedimiento;

EJEMPLO :

ALTER PROCEDURE ESCANDALLO_CONTROLA (PADRE VARCHAR(10),

HIJO VARCHAR(10))

AS

DECLARE VARIABLE M VARCHAR(10) ;

BEGIN

FOR SELECT MAESTRO FROM ART_ESCANDALLO WHERE (DETALLE = :PADRE ) INTO :M

DO BEGIN

IF ( M = HIJO ) THEN EXCEPTION ERROR_ESCANDALLO ;

EXECUTE PROCEDURE ESCANDALLO_CONTROLA :M,:HIJO;

END

END

La sintaxis del cuerpo del procedimiento se irá explicando en los próximos apartados, en el anterior ejemplo se ha utilizado para indicar las modificaciones.

Hay que tener mucho cuidado al modificar el orden y tipo de los parámetros de un procedimiento, tanto para el código escrito en el cuerpo, como para los otros procesos que lo estén utilizando.

Un procedimiento puede ser modificado en su totalidad, tanto parámetros como cuerpo del procedimiento.
   

ELIMINACIÓN DE PROCEDIMIENTOS. DROP PROCEDURE

La sentencia DROP PROCEDURE borra un procedimiento de la base de datos.

Hay que tener en cuenta que:

NOTA: Para tener una idea de los procedimientos y sus dependencias, utilice SHOW PROCEDURE.
 
 

La sintaxis es:

DROP PROCEDURE nombre;

Ejemplo:

DROP PROCEDURE ESCANDALLO_CONTROLA;

 

COMANDOS ADICIONALES DEL LENGUAJE DE LOS PROCEDIMIENTOS

Mas que comandos, se podrían definir como sentencias para procedimientos. Las sentencias disponible definen la sintaxis utilizada para crear el cuerpo del procedimiento. Esta sintaxis es resumida en el cuadro 3 de el siguiente ítem de tema.
  

RESUMEN DE SENTENCIAS PARA PROCEDIMIENTOS

Las sentencias aquí utilizadas corresponden al LENGUAJE DE PROCEDIMIENTOS Y TRIGGERS; la lista del cuadro 3, corresponden a las instrucciones que pueden utilizarse el los procedimientos almacenados.

Cuadro 3
 

BEGIN...END

Define un bloque se sentencias que se ejecutan como uno.

Variable = expresión

Sentencia de asignación, la cual asigna el valor de una expresión a una variable local.

/*Comentario */

Comentario del programador.

EXCEPTION nombre

Dispara una excepción. Una excepción es un error definido por el usuario, el cual retorna un mensaje de error a la aplicación, al menos que se utilice WHEN.

EXECUTE PROCEDURE

Nombre [variable[,variable..]

[RETURNING_VALUES

variable[,variable..]]

Ejecuta procedimientos almacenados, con los argumentos de entrada listados, retornando valores en la lista de argumentos de salida. Todas las variables deben de ser locales.

FOR <Sentencia Select

DO <Sentencia

Repite la sentencia de bloque seguida al DO , por cada fila retornada de la sentencia SELECT.

<Sentencia Select

Una sentencia SELECT simple, excepto que la cláusula INTO debe venir incluida.

<Sentencia :

Cualquier sentencia del lenguaje TRIGGER en una bloque BEGIN..END.

IF <Condición THEN

<Sentencia ELSE

<Sentencia

Se prueba la <Condición, si es verdadero, se ejecuta el bloque seguido a THEN, si es falso, se ejecuta la sentencia seguida al ELSE.

<condición

Una expresión booleana (TRUE, FALSE, UNKNOWN), generalmente son dos expresiones como operando de un operador de comparación.

POST_EVENT nombre

Graba el evento.

WHILE <Condición

DO <Sentencia

Mientras que la condición es verdadera, ejecuta la sentencia.

WHEN 

{<error [, <error…]|ANY}

DO <Sentencia

Sentencia de manejo de errores. Cuando uno de los errores especificados ocurre, se ejecuta la sentencia. Las sentencias WHEN deben de ir al final de un bloque, antes del END.

<error

Corresponde a EXCEPTION nombre, SQLCODE codigo_error o GDSCODE número. ANY , maneja cualquier error.

SUSPEND

En un procedimiento SELECT suspende la ejecución hasta el próximo FETCH. Retorna valores de salida.

EXIT

Salta el END del procedimiento.

 

LOS COMANDOS BEGIN END

Define un bloque se sentencias que se ejecutan como uno. La forma como se define un bloque, es iniciando con la instrucción BEGIN y finalizando con END.

Las instrucciones que pueden manipular bloques son :

Ejemplo :

CREATE PROCEDURE LOG_ENTRADAS_ENTRADA (MAQUINA VARCHAR(31), NOMBRE VARCHAR(31))
RETURNS (ENTRADA INTEGER, USUARIO INTEGER, FECHA DATE, EJERCICIO CHAR(4))
AS
BEGIN

....

END

Ejemplo:

BEGIN /* BEGIN del cuerpo del procedimiento*/

....

FOR SELECT ARTICULO FROM ART_ARTICULOS INTO :ARTICULO
DO

BEGIN /* BEGIN del bloque de la sentencia FOR SELECT*/
ARTTMP = NULL ;
SELECT ARTICULO FROM ART_EXISTENCIAS WHERE ((ARTICULO = :ARTICULO)
AND (ALMACEN = :ALMACEN ))
INTO :ARTTMP ;
IF ( ARTTMP IS NULL )THEN
INSERT INTO ART_EXISTENCIAS(ARTICULO,ALMACEN)
VALUES(:ARTICULO,:ALMACEN) ;
END /* END del bloque de la sentencia FOR SELECT.*/
....

END /*END del cuerpo del procedimiento*/

Ejemplo:

...

IF ( TITULO IS NULL ) THEN
BEGIN /* BEGIN del bloque del IF.*/
SI = 0 ;
SUSPEND ;
END /* END del bloque del IF*/
....

Ejemplo :

...

BEGIN /* BEGIN del cuerpo del procedimiento*/
 

CONTADOR = 1 ;
RESULTADO = 1 ;
WHILE ( CONTADOR <= EXPONENTE ) DO
BEGIN /* BEGIN del bloque de la instrucción WHILE*/
RESULTADO = ( RESULTADO * BASE ) ;
CONTADOR = ( CONTADOR + 1 ) ;
END /* END del bloque de la instrucción WHILE.*/
....

END /*END del cuerpo del procedimiento*/

Ejemplo :

BEGIN /* BEGIN del cuerpo del procedimiento*/

...

WHEN SQLCODE -530 DO

BEGIN /* BEGIN del bloque de la instrucción WHEN*/

VALOR = 1;

SUSPEND ;

END /END del bloque de la instrucción WHEN*/
END /*END del cuerpo del procedimiento*/
 

COMENTARIOS

Los comentario se colocan entre /* y */. Los comentarios siempre serán útiles, tanto para el programador, como para los futuros programadores de la aplicación, ya que le permitirán tener una guía. Es aconsejable no solo colocar comentarios, sino buenos comentarios, que permitan de alguna forma leer el código fuente sin necesidad de realizar procesos complejos para entenderlo.

Ejemplo :

CREATE PROCEDURE POTENCIA (BASE INTEGER, EXPONENTE INTEGER)
RETURNS (RESULTADO DOUBLE PRECISION)
AS
DECLARE VARIABLE CONTADOR INTEGER ;
BEGIN

/* Este procedimiento toma como parámetros la base y el exponente al que hay que */

/* Elevar la base para calcular la potencia. */

CONTADOR = 1 ; /* Lleva las interacciones desde el valor 1 hasta el valor del exponente */
RESULTADO = 1 ; /* Es el acumulador donde se almacenará el valor final de la potencia */
WHILE ( CONTADOR <= EXPONENTE ) DO
BEGIN

/* La lógica consiste en ir multiplicando la base por ella misma Exponente veces */
RESULTADO = ( RESULTADO * BASE ) ;
CONTADOR = ( CONTADOR + 1 ) ;
END
END

 

ASIGNACIONES

La asignación se ha definido como :

Variable = Expresión.

Hay que notar que el resultado de la expresión se almacena en una variable, así el lado derecho queda definido como una variable, donde VARIABLE puede ser un valor de un parámetro de salida o una variable declarada con DECLARE VARIABLE.

La expresión puede ser :

Ejemplo:

RESULTADO = ( RESULTADO * BASE ) ;
PER_CAL = PERIODO ;

Ejemplo :

D_HASTA = D_DESDE - 1 ;

Ejemplo :

CODIGO = GEN_ID( CONTA_CLIENTES , 1 ) ;

Explicaremos más adelante la sintaxis para la creación de generadores y su significado en las base de datos Interbase.
 
 

Ejemplo :

VALOR := CONCAT(VALOR1,VALOR2);

Donde CONCAT es alguna función definida en una DLL, por ejemplo.

Ejemplo :

D_HASTA = CAST(('12-31-' || EJERCICIO)AS DATE ) ;

En este caso se asigna un valor fecha, a la variable D_HASTA a partir de la variable EJERCICIO de tipo CHAR.
 

BIFURACIONES USANDO IF THEN ELSE

Las instrucciones condicionales son muy importantes es todo lenguaje que se este utilizando, podría decirse que no tiene sentido un lenguaje sin instrucciones IF...THEN..

La sintaxis para escribir esta clase de instrucciones es muy similar a la de muchos lenguajes de programación, aquí incluimos la utilizada por los Procedimientos almacenados.

IF <Condición THEN

<Sentencia ELSE

<Sentencia

La forma de evaluarse cual de las dos sentencias se ejecuta, depende del valor resultante en la condición, si es verdadero, se ejecutara la primera sentencia, si en falso, se ejecutará la sentencia correspondiente al ELSE.

La sentencia corresponde a cualquier sentencia que pueda ejecutarse en un procedimientos almacenado, incluso puede ser otro IF...THEN.

Por medio de ejemplos se ilustrará como puede ser establecida la condición de la Condición.
 

EJEMPLOS:

1.

IF ( DESTINO = -1 ) THEN
UPDATE EMP_CLIENTES SET TOTAL_VENTAS = ( TOTAL_VENTAS + :TOTAL )
WHERE TERCERO = :TERCERO ;

Este ejemplo ilustra la forma más simple de una instrucción IF, la comparación de igualdad por medio del operador =. Se pueden utilizar otros operadores de comparación como son:
 

< Menor que

> Mayor que

= Igual

<= Menor o Igual

= Mayor o Igual

IS NOT NULL No es de valor nulo

IS NULL Es de valor nulo.
 

Como por ejemplo

....

IF ( USUARIO IS NULL ) THEN
BEGIN
....

 

2.

IF ( PERIODO IN ('00','13','17','19') ) THEN PER_CAL = '01' ;

Se puede realizar la comparación de una variable en un rango de valores, estos son escritos como una lista separada por comas (,) y cada valor del mismo tipo de la variable.
 

3.

IF ((DEBE<0)OR(HABER<0)) THEN SEPUEDE = 0 ;

Se pueden utilizar los operadores lógicos y los paréntesis para agrupar valores booleanos.

Los operadores lógicos AND y OR y NOT.
 

4.

IF ( PERIODO = '14' ) THEN PER_CAL = '04' ;

Si se van a comparar valores de tipo CHAR con constantes, estas se encierran entre comillas simples.
 

BUCLES USANDO WHILE DO

La única forma de realizar bucles o secuencias repetitivas es a través del WHILE DO, me refiero a sentencias repetitivas sin utilizar conjuntos de datos, que se verá mas adelante, que pueden ser implementadas con sentencias FOR SELECT.

La sintaxis utilizada es muy común a la utilizada por pascal:
WHILE <Condición

DO <Sentencia

La condición de la claúsula <Condición tiene las mismas características que la condición que se utiliza en la sentencia IF.. THEN. Por lo tanto sobra explicarla de nuevo en esta sección.

La sentencia corresponde a cualquier sentencia válida en el LENGUAJE DE PROCEDIMIENTOS Y TRIGGERS.

Utilizar bucles en los procedimientos almacenados es muy útil para realizar cálculos, pero no para hacer navegación con las tablas o vistas, para ello se utiliza la instrucción FOR SELECT.
 

EJEMPLO:

1.

CREATE PROCEDURE POTENCIA (BASE INTEGER, EXPONENTE INTEGER)
RETURNS (RESULTADO DOUBLE PRECISION)
AS
DECLARE VARIABLE CONTADOR INTEGER ;
BEGIN
CONTADOR = 1 ;
RESULTADO = 1 ;
WHILE ( CONTADOR <= EXPONENTE ) DO
BEGIN
RESULTADO = ( RESULTADO * BASE ) ;
CONTADOR = ( CONTADOR + 1 ) ;
END
END

Esta es la forma práctica de realizar un proceso POTENCIA.

2.

FOR SELECT JOB_CODE, JOB_GRADE, JOB_COUNTRY

FROM JOB

WHERE LANGUAGE_REQ IS NOT NULL

INTO :CODE, :GRADE, :CTY

DO

BEGIN

I = 1;

WHILE (I <= 5) DO

BEGIN

SELECT LANGUAGE_REQ[:I] FROM JOB

WHERE ((JOB_CODE = :CODE) AND (JOB_GRADE = :GRADE)

AND (JOB_COUNTRY = :CTY)) INTO :LANG;

I = I + 1;

SUSPEND;

END

END

El anterior ejemplo es la forma de mostrar el contenido de un campo de tipo ARRAY, para ello, es necesario utilizar la sentencia WHILE DO.
 

USANDO DECLARACIONES DE TIPO DML DENTRO DE LOS PROCEDIMIENTOS

USANDO SELECT EN UN PROCEDIMIENTO

La sentencias SELECT se pueden utilizar dentro de un procedimiento almacenado, pero si devuelven un solo valor. Pueden ser utilizadas para recuperar valores de los campos de las tablas, que puedan ser manipulados para cualquier proceso referente al PROCEDIMENTO ALMACENADO que la utilice.

Debe de contener una claúsula INTO donde se almacene el valor de retorno de la consulta.

Ejemplo:

1.

CREATE PROCEDURE DAME_NIVELES_CONTABLES (EMPRESA SMALLINT, EJERCICIO CHAR(4))
RETURNS (NIVELES SMALLINT)
AS
BEGIN
SELECT MAX(NIVEL)FROM CON_CUENTAS_NIVELES
WHERE ((EMPRESA=:EMPRESA)AND(EJERCICIO=:EJERCICIO)) INTO :NIVELES ;
END

En este ejemplo se ilustra como la instrucción SELECT retorna un solo valor, que almacena en la variable niveles que es el parámetro de salida del procedimiento.
 
 

2.

CREATE PROCEDURE LOG_ENTRADAS_VALIDA_SA (NOMBRE VARCHAR(31), ENTRADA INTEGER)
RETURNS (USUARIO SMALLINT,
CLAVE VARCHAR(31), NIVEL SMALLINT, EMPRESA SMALLINT, EJERCICIO CHAR(4), ICONOS SMALLINT)
AS
BEGIN
SELECT USUARIO,CLAVE,NIVEL,EMPRESA,EJERCICIO,ICONOS_SIMPLES FROM SYS_USUARIOS
WHERE (NOMBRE=:NOMBRE) INTO :USUARIO,:CLAVE,:NIVEL,:EMPRESA,:EJERCICIO,:ICONOS ;

UPDATE SYS_ENTRADAS SET USUARIO = :USUARIO ,
EMPRESA = :EMPRESA WHERE ENTRADA = :ENTRADA ;
END

En este ejemplo se ilustra un forma de realizar una sentencia UPDATE con los valores de retorno de la instrucción SELECT.

 

USANDO INSERT, UPDATE Y DELETE

En el último ejemplo se puede observar la forma de realizar una sentencia UPDATE. Una de las ventajas de los procedimientos almacenados, es que permiten realizar actualizaciones, inserciones y borrados de datos de cualquier tabla de la base de datos.

Esta característica permite realizar verdaderos procesos de transacción, accediendo a muchos recursos de la base de datos de una forma centralizada.

EJEMPLOS:

1.

CREATE PROCEDURE LOG_ENTRADAS_SALIDA (ENTRADA INTEGER)
AS
BEGIN
UPDATE SYS_ENTRADAS SET FEC_SALIDA = 'NOW' WHERE ENTRADA = :ENTRADA ;
END

El procedimiento LOG_ENTRADAS_SALIDA actualiza la tabla SYS_ENTRADAS con la fecha actual, dado un valor clave ENTRADA.

2.

CREATE PROCEDURE LOG_ENTRADAS_ALTA (MAQUINA VARCHAR(31), LOGIN VARCHAR(31), OS VARCHAR(100))
RETURNS (ENTRADA INTEGER,
FECHA DATE)
AS
DECLARE VARIABLE UBICACION SMALLINT ;
BEGIN
SELECT UBICACION FROM SYS_UBICACIONES
WHERE ((MAQUINA=:MAQUINA) AND (LOGIN=:LOGIN) AND (SISTEMA=:OS))
INTO :UBICACION ;
IF ( UBICACION IS NULL ) THEN
BEGIN
UBICACION = GEN_ID(CONTA_UBICACIONES,1) ;
INSERT INTO SYS_UBICACIONES(UBICACION,MAQUINA,LOGIN,SISTEMA)
VALUES(:UBICACION,:MAQUINA,:LOGIN,:OS);
END
ENTRADA = GEN_ID( CONTA_ENTRADAS,1) ;
INSERT INTO SYS_ENTRADAS(ENTRADA,USUARIO,EMPRESA,UBICACION)
VALUES(:ENTRADA,0,0,:UBICACION) ;
FECHA = 'NOW' ;
END

Cuando se ejecuta el procedimiento LOG_ENTRADAS_ALTA, se inserta en la tabla SYS_ENTRADAS el registro de la entrada del usuario.

3.

CREATE PROCEDURE LOG_ENTRADAS_VACIA_2 (ENTRADA INTEGER)
AS
BEGIN
DELETE FROM SYS_ENTRADAS WHERE ( ENTRADA = :ENTRADA ) ;
WHEN SQLCODE -530 DO SUSPEND ;
END

Este procedimiento se utiliza para borrar las entradas de la tabla SYS_ENTRADAS.

 

LA DECLARACIÓN FOR SELECT DO

La orden FOR SELECT retorna múltiples registros en un procedimiento. La sintaxis utilizada es:

FOR <Sentencia Select

DO <Sentencia

La sentencia FOR SELECT es diferente de la sentencia SELECT, ya que es obligatorio incluir la claúsula INTO dentro de la sentencia SELECT para el FOR SELECT.

Otra diferencia fundamental es la forma como se ejecuta la sentencia FOR SELECT. Por cada registro que retorna la instrucción FOR SELECT, se ejecutan las sentencias de la instrucción DO.

La serie de ejemplo siguientes, ilustra la utilización de la instrucción FOR SELECT.

Ejemplos:

1.

CREATE PROCEDURE CONTACTOS_AJUSTA
AS
DECLARE VARIABLE TERCERO INTEGER ;
DECLARE VARIABLE CONTACTO SMALLINT ;
BEGIN
FOR SELECT DISTINCT TERCERO FROM SYS_CONTACTOS INTO :TERCERO
DO

BEGIN

SELECT MAX(CONTACTO)

FROM SYS_CONTACTOS

WHERE (TERCERO=:TERCERO) INTO :CONTACTO ;

IF (CONTACTO IS NULL) THEN CONTACTO = 0 ;
 

UPDATE SYS_TERCEROS SET CONTACTOS=:CONTACTO

WHERE (TERCERO=:TERCERO) ;

END

END

Cuando se ejecuta el procedimiento CONTACTOS AJUSTA, primero realiza una selección de todos los terceros de la tabla contactos, por cada tercero selecciona el valor del contacto más alto, y lo actualiza en el campo de la tabla SYS_TERCEROS, ajustando el número de contactos del tercero.

2.

Este ejemplo muestra la creación de un procedimiento que contiene dos FOR SELECT anidados. Tiene el mismo comportamiento de dos ciclos anidados en programación. Las dos instrucciones están completamente relacionadas, para realizar un borrado en propagación.

CREATE PROCEDURE CON_CUENTAS_BAJA_PROPAGA (EMPRESA SMALLINT, EJERCICIO CHAR(4))
AS
DECLARE VARIABLE NIVEL SMALLINT ;
DECLARE VARIABLE CANAL SMALLINT ;
BEGIN
FOR SELECT CANAL FROM CON_CANALES WHERE((EMPRESA=:EMPRESA)AND(EJERCICIO=:EJERCICIO)) ORDER BY CANAL INTO :CANAL DO
FOR SELECT NIVEL FROM CON_CUENTAS_NIVELES
WHERE(( EMPRESA=:EMPRESA )AND(EJERCICIO=:EJERCICIO))
ORDER BY NIVEL DESC INTO :NIVEL DO
DELETE FROM CON_CUENTAS WHERE ((EMPRESA=:EMPRESA) AND (CANAL=:CANAL)

AND(EJERCICIO=:EJERCICIO)AND(NIVEL=:NIVEL)) ;

END
 

PROCEDIMIENTOS QUE ACEPTAN PARÁMETROS

Los parámetros de entrada son utilizados para pasar valores de una aplicación a un procedimiento; son declarados como una lista separada por comas y entre paréntesis. Una vez declarados pueden ser utilizados en cualquier lugar donde una expresión pueda aparecer.

Todos los parámetros son pasados por valor, es decir que si se modifican dentro del procedimiento no afecta su valor externo.

Ejemplo:

La siguiente sentencia declara un procedimiento con dos valores de entrada.

CREATE PROCEDURE

NUEVA_TERCEROCUENTA (TERCERO INTEGER, CUENTACOMP CHAR(23))

AS
 

PROCEDIMIENTOS QUE RETORNAN VALORES

Los parámetros de salida son utilizados para retornar valores a las llamadas desde aplicaciones. Son declarados como una lista separada por comas y entre paréntesis, después de la palabra RETURNS.

Una vez declarado puede ser utilizado en cualquier parte del código donde una expresión pueda aparecer
 
 

Ejemplo:
 
 

CREATE PROCEDURE DAME_PRODUCTO

RETURNS (CODIGO INTEGER)

AS

BEGIN

CODIGO = GEN_ID( CONTA_PRODUCTOS , 1 ) ;

END
 
 

Un procedimiento que retorna valores lo hace por medio de SUSPEND.
 
 

En una instrucción SELECT que utiliza valores de un procedimiento los nombres de las columnas deben empatar con los nombres de los parámetros de salida y sus tipos de datos.
 
 

Si es un procedimiento ejecutable no es necesario que empaten los valores de salida.
 

PROCEDIMIENTOS QUE DEVUELVEN MÚLTIPLES REGISTROS. LA ORDEN SUSPEND

La sentencia SUSPEND suspende la ejecución de un procedimiento almacenado. SUSPEND también retorna valores en los parámetros de salida de un procedimiento.

SUSPEND no debería ser utilizado en procedimiento ejecutables, ya que la próxima sentencia nunca es ejecutada. Debería de ser utilizada EXIT para indicar explícitamente que la sentencia termina el procedimiento.

Para observar mejor ese comportamiento se utiliza la siguiente tabla:
 
 
 

Tipo de procedimiento

Comando

Procedimiento Select

SUSPEND

Suspende la ejecución del procedimiento hasta que el próximo FETCH retorne valores.

EXIT

Salta al final END

END

Retorna control a la aplicación 

Establece SQLCODE a 100

Procedimiento ejecutable

SUSPEND : 

Salta al final END

No recomendado

EXIT

Salta al final END

END

Retorna valores 

Retorna control a la aplicación

Ejemplo:

CREATE PROCEDURE P RETURNS (r INTEGER)

AS

BEGIN

r = 0;

WHILE (r < 5) DO

BEGIN

r = r + 1;

SUSPEND;

IF (r = 3) THEN

EXIT;

END

END;

Si se utiliza el procedimiento en un SELECT entonces:

SELECT * FROM P;

Retorna valores de 1,2 y 3 a la aplicación que lo llama, ya que el SUSPEND retorna el corriente valore de "r" a la aplicación. El procedimiento termina cuando él encuentra EXIT.

Si el procedimiento es utilizado como un procedimiento ejecutable, por ejemplo:

EXECUTE PROCEDURE P;

Entonces retorna 1, ya que SUSPEND termina el procedimiento y retorna el valor corriente de "r" a la aplicación. Esto no es recomendado, pero es incluido a modo de ejemplo.

CONCEPTO Y USO DE LOS DISPARADORES EN INTERBASE. TRIGGERS

Un TRIGGER es una rutina asociada con una tabla o vista que automáticamente ejecuta una acción cuando un registro o fila en una tabla o vista es insertada, actualizada o borrada.

Un TRIGGER nunca es utilizado directamente, el automáticamente se ejecuta cuando un usuario intenta hacer un INSERT, UPDATE o DELETE en el registro de una tabla.

La utilización de TRIGGERS tiene una serie de ventajas:

 

LA ESTRUCTURA DE UN TRIGGER

Un TRIGGER es definido con CREATE TRIGGER, el cual esta compuesto de CABECERA(header) y CUERPO(body).
 

La cabecera contiene:  

El cuerpo (body) contiene:

Todas las sentencias de código terminan con punto y coma(;), por lo tanto hay que utilizar SET TERM para modificarlo antes de la definición del TRIGGRES y luego colocarlo con SET TERM de nuevo.
 

La sintaxis es:

CREATE TRIGGER nombre FOR { tabla | vista}

[ACTIVE | INACTIVE]

{BEFORE | AFTER} {DELETE | INSERT | UPDATE}

[POSITION numero]

AS < Cuerpo del TRIGGER

< Cuerpo del TRIGGER =[< Lista de declaración de variables>]< bloque>

< Lista de declaración de variables > =

DECLARE VARIABLE variable Tipo_de_dato;

[DECLARE VARIABLE variable Tipo_de_dato; …]

< bloque > =

BEGIN

< Sentencia >

[< Sentencia … >]

END

< Sentencia >= {< bloque > | Sentencia;}
 

Donde se tiene que:
 

Nombre

Nombre del TRIGGER, debe de ser único en la base de datos.

Tabla

Nombre de la tabla o vista causante de que se dispare en TRIGGER.

ACTIVE O INCATIVE.

Especifica la acción del TRIGGER en la transacción.

BEFORE o AFTER

Especifica si el TRIGGER se dispara : 

BEFORE : Antes de la operación asociada. 

AFTER : Después de la operación asociada. 

Las operaciones asociadas son : INSERT, DELETE y UPDATE.

DELETE, UPDATE INSERT.

Especifica la operación que causa que el TRIGGER se dispare.

POSITION número

Especifica el orden en que se disparan los TRIGGERS asociados a una acción.

Los TRIGGERS para una tabla no tienen que ser consecutivos, se disparan también en orden alfabético.

DECLARE VARIABLE Variable < Tipo_de_dato

Declara las variables locales utilizadas solamente en el TRIGGER. Cada declaración debe ser declarada con DECLARE VARIABLE y seguida por un punto y coma (;).

Variable : Nombre de la variable local.

Tipo_de_dato : tipo de dato de la variable local.

Terminador

Terminador definido por SET TERM, el cual significa el final del cuerpo del TRIGGER.

Sentencia

Una sentencia en lenguaje de TRIGGER y procedimiento.

 

Por medio de los siguientes ejemplos se puede entender mejor el cuadro anterior.
 

1.

CREATE TRIGGER APUNTES_ACT_ASIENTO FOR CON_APUNTES

ACTIVE AFTER INSERT POSITION 0

AS

BEGIN

UPDATE CON_ASIENTOS SET TOTAL = ( TOTAL + NEW.TOTAL )

WHERE ( (EJERCICIO=NEW.EJERCICIO) AND

(NASIENTO =NEW.NASIENTO )) ;

END
 
 

Este es un TRIGGER de respuesta definido para la tabla CON_APUNTES, que se dispara después de cualquier inserción de un registro.

 

2.

CREATE TRIGGER SYS_CONSTANTES_BI0 FOR SYS_CONSTANTES

ACTIVE BEFORE INSERT POSITION 0

AS

BEGIN

EXCEPTION ERROR_REGISTRO_UNICO ;

END
 
 

Este TRIGGER se dispara antes que se inserte un registro en la tabla SYS_CONSTANTES.

La utilización de NEW y OLD se explicará más adelante.
 
 

EL LENGUAJE DE TRIGGER

El lenguaje de Procedimiento y TRIGGERS en un completo lenguaje para almacenar procedimientos y TRIGGERS.

Este lenguaje incluye:

Tanto los Procedimientos como los TRIGGERS utilizan el mismo lenguaje, con algunas diferencias

 

RESUMEN DE SENTENCIAS PARA TRIGGERS
 

BEGIN...END

Define un bloque se sentencias que se ejecutan como uno.

Variable = expresión

Sentencia de asignación, la cual asigna el valor de una expresión a una variable local.

/*Comentario */

Comentario del programador.

EXCEPTION nombre

Dispara una excepción. Una excepción es un error definido por el usuario, el cual retorna un mensaje de error a la aplicación, al menos que se utilice WHEN.

EXECUTE PROCEDURE

Nombre [variable[,variable..]

[RETURNING_VALUES

variable[,variable..]]

Ejecuta procedimientos almacenados, con los argumentos de entrada listados, retornando valores en la lista de argumentos de salida. Todas las variables deben de ser locales.

FOR <Sentencia Select

DO <Sentencia

Repite la sentencia de bloque seguida al DO , por cada fila retornada de la sentencia SELECT.

<Sentencia SELECT : Una sentencia SELECT simple, excepto que la cláusula INTO debe venir incluida.

<Sentencia : Cualquier sentencia del lenguaje TRIGGER en una bloque BEGIN..END.

IF <Condición THEN

<Sentencia ELSE

<Sentencia

Se prueba la <Condición, si es verdadero, se ejecuta el bloque seguido a THEN, si es falso, se ejecuta la sentencia seguida al ELSE.

<condición : Una expresión booleana (TRUE, FALSE, UNKNOWN), generalmente son dos expresiones como operandos de un operador de comparación.

NEW.columna

Nueva variable de contexto que indica un nuevo valor de la columna en una operación INSERT o UPDATE.

OLD.columna

Variable de contexto que indica un valor anterior antes de una operación UPDATE o DELETE.

POST_EVENT nombre

Graba el evento.

WHEN 

{<error [, <error…]|ANY}

DO <Sentencia

Sentencia de manejo de errores. Cuando uno de los errores especificados ocurre, se ejecuta la sentencia. Las sentencias WHEN deben de ir al final de un bloque, antes del END.

<error : Corresponde a EXCEPTION nombre, SQLCODE codigo_error o GDSCODE número. 

ANY, maneja cualquier error.

WHILE <Condición

DO <Sentencia

Mientras que la condición es verdadera, ejecuta la sentencia.


 

La utilización de estas sentencias es similar a las sentencias utilizadas en procedimientos, la única diferencia es la utilización de las variables de contexto NEW y OLD que se verán más adelante.

Otro concepto importante para no dejarlo de lado, consiste en la utilización de la palabra reservada POSITION, para ello se puede observar el siguiente ejemplo.
 
 

Ejemplo de Cabeceras:

CREATE TRIGGER A FOR CONSTANTES BEFORE UPDATE POSITION 5 AS …

CREATE TRIGGER B FOR CONSTANTES BEFORE UPDATE POSITION 0 AS …

CREATE TRIGGER C FOR CONSTANTES AFTER UPDATE POSITION 5 AS …

CREATE TRIGGER D FOR CONSTANTES AFTER UPDATE POSITION 3 AS …

Cuando la siguiente actualización se ejecuta:

UPDATE CONSTANTES SET MODO_DE_CONTADORES = ‘1’

WHERE MODO_DE_CONTADORES = ‘0’

;

La siguiente secuencia se dispara:

TRIGGER B , A , la actualización ocurre,

TRIGGER D , entonces C finaliza.
 

UTILIZACIÓN DE OLD Y NEW

Los TRIGGERS pueden utilizar dos variables de contexto: OLD y NEW.

La variable de contexto OLD se refiere al valor corriente o previo en un registro que esta siendo actualizado o borrado. OLD no es utilizado para INSERT ( No es lógico , no hay anterior valor). NEW no es utilizado para DELETE ( no es lógico porque no hay nuevo valor). Las variables de contexto son utilizadas para comparar valores de una columna antes y después de ser modificadas.

El siguiente ejemplo muestra la utilización de estas sentencias.

SET TERM !! ;

CREATE TRIGGER EDITA_VENTAS_AU0 FOR VENTAS

AFTER UPDATE

BEGIN
UPDATE CLIENTES SET ACUMULADO_VENTAS = (ACUMULADO_VENTAS - OLD.VALOR) WHERE ( TERCERO = OLD.CLIENTE ) ;
UPDATE CLIENTES SET ACUMULADO_VENTAS = (ACUMULADO_VENTAS + NEW.VALOR) WHERE ( TERCERO = NEW.CLIENTE );
END

SET TERM ; !!

Este TRIGGER se dispara después que se actualiza la tabla Ventas, Actualizando la tabla clientes con los nuevos acumulados de ventas
 

UTILIZANDO GENERADORES

Un generador es un objeto que es automáticamente incrementado cada vez que la función GEN_ID() es llamada.

Los generadores son utilizados para asegurar que un número insertado en una columna sea único.

Un Generador es creado con CREATE GENERATOR e inicializado con SET GENERATOR, si no son inicializados comienzan con un valor de 1.

Los generadores deben de ser creados antes de utilizar GEN_ID()

La sintaxis de GEN_ID() es :
 
 

GEN_ID( nombre , paso)

Donde nombre es un generador creado anteriormente y paso se refiere a la cantidad que se incrementara el generador, Paso puede ser un valor entero o el resultado de una expresión.

Lo siguientes ejemplos ilustran la utilización del OLD y el NEW, junto con los generadors:

1.

CREATE TRIGGER Alta_Movimientos_bi0 FOR MOVIMIENTOS

BEFORE INSERT AS

BEGIN

NEW.MOVIMIENTO = GEN_ID( CONTA_MOVIMIENTOS , 1 ) ;

END !!
 
 

2.

CREATE TRIGGER ART_FAMILIAS_BI0 FOR ART_FAMILIAS

ACTIVE BEFORE INSERT POSITION 0

AS

BEGIN

NEW.IVA = 1 ;

NEW.CUENTA_COMPRAS = '60000000' ;

NEW.CUENTA_VENTAS = '70000000' ;

NEW.TITULO = 'FARMACIA' ;

END
 
 

MODIFICANDO LOS TRIGGERS. ALTER TRIGGER

ALTER TRIGGER puede modificar :

La sintaxis es:

ALTER TRIGGER nombre

[ACTIVE | INACTIVE]

[{BEFORE |

AFTER} {

DELETE |

INSERT |

UPDATE}]

[POSITION numero]

AS < Cuerpo del TRIGGER ;

La sintaxis de ALTER TRIGGER es idéntica que la de CREATE TRIGGER. Excepto que FOR tabla, es omitida, ya que no se puede modificar la tabla donde el TRIGGER esta asociado.

Ejemplos:

1.

ALTER TRIGGER ALTA_MOVIMIENTOS_BI0

ACTIVE

BEFORE INSERT;

2.

ALTER TRIGGER ALTA_MOVIMIENTOS_BI0 FOR MOVIMIENTOS

BEFORE INSERT AS

BEGIN

NEW.MOVIMIENTO = GEN_ID( CONTA_MOVIMIENTOS , 2 ) ;

END

BORRANDO TRIGGERS . DROP TRIGGER

Un TRIGGER puede ser removido temporalmente o permanentemente. Para removerlo temporalmente se hace con ALTER TRIGGER y se especifica INACTIVE

Para borrarlo permanentemente se hace con DROP, cuya sintaxis es:

DROP TRIGGER nombre;

Ejemplo:

DROP TRIGGER ALTA_MOVIMIENTOS_BI0;
 

UTILIZANDO LOS TRIGGERS

Los TRIGGERS pueden utilizarse de muchas formas, he aquí algunos ejemplos:

Los triggers son almacenados en la base de datos, como también los procedimientos y excepciones.
 

¿QUÉ ES UNA EXCEPCIÓN?

Una excepción es un mensaje de error con nombre que puede ser disparado desde un procedimientos almacenado. Las excepciones son creadas con CREATE EXCEPTION, modificadas con ALTER EXCEPTION y eliminadas con DROP EXCEPTION.

Para disparar una excepción desde un procedimiento almacenado, se utiliza la instrucción EXCEPTION de la siguiente manera:

EXCEPTION Nombre_excepción;

Para poderse utilizar una excepción es necesario crearla y almacenarla en la base de datos mediante COMMIT.
 

CREANDO, MODIFICANDO Y BORRANDO EXCEPCIONES

Para crear una excepción se utiliza la siguiente sintaxis.
 

CREATE EXCEPTION nombre "<Mensaje";
 

Ejemplo:

CREATE EXCEPTION ERROR_ESTRUCTURA_BLOQUEADA "Estructura de contabilidad bloqueada".

Para modificar una excepción se utiliza la siguiente sintaxis:

ALTER EXCEPTION nombre "<Mensaje";

Ejemplo:

ALTER EXCEPTION ERROR_ESTRUCTURA_BLOQUEADA "Estructura bloqueada".

Para borrar una excepción se utiliza la siguiente sintaxis:

DROP EXCEPTION name;

Para poderla borrar es necesario que no este siendo utilizada.
 

DESENCADENANDO (RAISE) UNA EXCEPCIÓN

Para disparar una excepción desde un procedimiento almacenado, utilizar la siguiente sintaxis:

EXCEPTION nombre;

El "nombre" es el nombre de una excepción que existe en la base de datos.

Cuando una excepción es llamada o desencadenada sucede lo siguiente:

Si la excepción es manipulada con una instrucción WHEN, el comportamiento es diferente:

Ejemplo:

IF (any_sales 0) THEN

EXCEPTION REASSIGN_SALES;
 

ERRORES EN INTERBASE

Los procedimientos almacenados pueden manipular tres tipos de errores con una instrucción WHEN DO.

La instrucción WHEN ANY manipula cualquier tipo de errror.

La sintaxis para la instrucción WHEN DO es la siguiente:

WHEN {< error [, < error …] | ANY}

DO <Sentencias

< error ={EXCEPTION nombre de excepción | SQLCODE numero | GDSCODE código de error}
 
 

La instrucción WHEN permite manipular cualquier clase de error, sea una excepción creada por un usuario, un error del SQL o un error reportado por interbase. La instrucción WHEN debe de ir antes del END del bloque y es la última instrucción del bloque.
 
 

RESPUESTAS A LAS PREGUNTAS DE LA UNIDAD 8

  1. ¿Cuáles son los pasos a realizar para conseguir que un nuevo usuario pueda tener derecho de consulta sobre todas las tablas de una base de datos?

  2. En primer lugar se dará de alta en el servidor por medio del Server manager, de la utilidad gsec (comando add) o incluso se podría utilizar una herramienta propia que utilizase el API de interbase (en concreto la función isc_add_user).

    Posteriormente se le concederían los derechos de lectura (Select) para cada una de las tablas de la base de datos con el comando GRANT.
     
     
     
     

  3. ¿Cuál es el significado de las cláusulas ALL y PUBLIC del comando GRANT y qué ventajas e inconvenientes tiene el utilizarlas?.

  4. La cláusula ALL concede de una vez los derechos select,insert,update,delete y references.

    La clausula PUBLIC concede los derechos especificados a cualquier usuario.

    La ventaja es que se manejan varios derechos/usuarios con una sola cláusula, y el inconveniente es que se manejan en bloque, por lo que se conceden y revokan de la misma forma.

  5. Exponer tres motivos por los que puede ser interesante tomar medidas adicionales a las previstas por el modelo relacional y por el modelo de interbase ácerca de la seguridad y qué medidas se tomarían en cada caso.
    1. Para evitar que las bases de datos sean copiadas a otro servidor y los datos queden al descubierto: Limitar los derechos de acceso a nivel del S.O.
    2. Para evitar que por accidente las bases de datos sean borradas o cambiadas de sitio en el servidor: Limitar los derechos de acceso a nivel de S.O.
    3. En bases de datos distribuidas a clientes finales, para evitar que lalógica del sistema de información que reside en los procedimientos almacenados quede al descubierto: Eliminar el código fuente de los mismos borrándolo de las tablas del sistema.

 

PREGUNTAS DE LA UNIDAD 9
 
 

1. QUE ES UN PROCEDIMIENTO ALMACENADO.
 
 

2. Puede un TRIGGER ser utilizado directamente desde una aplicación
 
 

3. ¿QUÉ ES UNA EXCEPCIÓN?

 

INDICE

 

Objetivo

Panorámica

¿Qué es un procedimiento almacenado?

Ventajas de los procedimientos almacenados

¿Cuándo deben de usarse procedimientos almacenados?

Creación de procedimientos almacenados

Estructura de un procedimiento almacenado

Sintaxis para la creación del procecedimiento

Ejecutando procedimientos almacenados

Modificando y eliminando procedimientos almacenados

Comando adicionales del lenguaje de los procedimientos

Los comandos BEGIN END

Comentarios

Asignaciones

Bifuraciones usando IF THEN ELSE

Bucles usando WHILE DO

Usando declaraciones del tipo DML dentro de los procedimientos

Usando INSERT, UPDATE Y DELETE

La declaración FOR SELECT D.

Procedimientos que aceptan parámetros

Procedimientos que retornan valores

Procedimientos que devuelven multiples registros. La orden SUSPEND

Concepto y uso de los disparadores en InterBase. TRIGGERS

La estructura de un TRIGGERS

El lenguaje de TRIGGER

Resumen de sentencias para TRIGGERS

Utilización de OLD Y NEW

Utilizando generadores

Modificando los TRIGGERS

Borrando TRIGGERS

Utilizando los TRIGGERS

¿Qué es una excepción?

Creando, modificando y borrando excepciones

Desencadenando una excepción

Errores en InterBase

Respuestas a las preguntas de la Unidad 8

Preguntas de la Unidad 9