viernes, 25 de enero de 2013

Procedimientos almacenados

Para crear un procedimiento, MySQL nos ofrece la directiva CREATE PROCEDURE. Al crearlo éste es ligado o relacionado con la base de datos que se está usando, tal como cuando creamos una tabla, por ejemplo.

Para llamar a un procedimiento lo hacemos mediante la instrucción CALL. Desde un procedimiento podemos invocar a su vez a otros procedimientos o funciones.

Un procedimiento almacenado, al igual cualquiera de los procedimientos que podamos programar en nuestras aplicaciones utilizando cualquier lenguaje, tiene:

  • Un nombre.
  • Puede tener una lista de parámetros.
  • Tiene un contenido (sección también llamada definición del procedimiento: aquí
  • se especifica qué es lo que va a hacer y cómo).
  • Ese contenido puede estar compuesto por instrucciones sql, estructuras de control, declaración de variables locales, control de errores, etcétera.


MySQL sigue la sintaxis SQL:2003 para procedimientos almacenados, que también usa IBM DB2.

En resumen, la sintaxis de un procedimiento almacenado es la siguiente:

CREATE PROCEDURE nombre (parámetro)  
    [características] definición  

Puede haber más de un parámetro (se separan con comas) o puede no haber ninguno (en este caso deben seguir presentes los paréntesis, aunque no haya nada dentro).

Los parámetros tienen la siguiente estructura: modo nombre tipo

Donde:

  • modo: es opcional y puede ser IN (el valor por defecto, son los parámetros que el procedimiento recibirá), OUT (son los parámetros que el procedimiento podrá modificar) INOUT (mezcla de los dos anteriores).
  • nombre: es el nombre del parámetro.
  • tipo: es cualquier tipo de dato de los provistos por MySQL.
  • Dentro de características es posible incluir comentarios o definir si el procedimiento obtendrá los mismos resultados ante entradas iguales, entre otras cosas.
  • definición: es el cuerpo del procedimiento y está compuesto por el procedimiento en sí: aquí se define qué hace, cómo lo hace y bajo qué circunstancias lo hace.


CREATE PROCEDURE simpleproc (INT param1 INT)
BEGIN
    SELECT * FROM siniestro limit 0, param1;
    END


 CREATE PROCEDURE procedimiento2 (IN a INTEGER)
BEGIN
DECLARE variable CHAR(20);
IF a > 10 THEN
SET variable = 'mayor a 10';
ELSE
SET variable = 'menor o igual a 10';
END IF;
select variable;
END


CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE a CHAR(16);
  DECLARE b,c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

  OPEN cur1;
  OPEN cur2;

  REPEAT
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF NOT done THEN
       IF b < c THEN
          INSERT INTO test.t3 VALUES (a,b);
       ELSE
          INSERT INTO test.t3 VALUES (a,c);
       END IF;
    END IF;
  UNTIL done END REPEAT;

  CLOSE cur1;
  CLOSE cur2;
END




CREATE DEFINER = 'root'@'localhost' PROCEDURE `compras`()
    DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
  -- Declare local variables
   DECLARE done BOOLEAN DEFAULT 0;
   DECLARE o INT;
   DECLARE t DECIMAL(8,2);
   -- Declare the cursor
   DECLARE ordernumbers CURSOR
   FOR
   SELECT id FROM compra;
   -- Declare continue handler
   DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
   -- Create a table to store the results
   CREATE TEMPORARY TABLE IF NOT EXISTS ordertotals
      (order_num INT, total DECIMAL(8,2));
   -- Open the cursor
   OPEN ordernumbers;
   -- Loop through all rows
   REPEAT
      -- Get order number
      FETCH ordernumbers INTO o;
      -- Get the total for this order
      -- Insert order and total into ordertotals
      INSERT INTO ordertotals(order_num, total)
      VALUES(o, t);
   -- End of loop
   UNTIL done END REPEAT;
   -- Close the cursor
   CLOSE ordernumbers;  
   select * from ordertotals;  
   drop table ordertotals;
END;





BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS temporal (id INT, dni varchar(8));
     
INSERT INTO temporal(id, dni) VALUES(1, "BLAS");
     
    select * from temporal;  
    drop table temporal;
END

No hay comentarios:

Publicar un comentario