Conoce SQL – Lenguaje procedimental 1 – Estructura y sintaxis

SQL es un gran lenguaje pero también tiene limitaciones. Pero como siempre que hay una limitación, se inventa algo para elminarla. Este es el caso del lenguaje procedimental de los SGBD. Es un lenguaje como C, JAVA y esos de “toda la vida”. Esto nos proporciona principalmente la posibilidad de crear variables, bucles… vamos, un programa.

Un problema de estos lenguajes es que no son nada estandares y cada SGBD tiene el suyo y la sintaxis es diferente. La verdad que sabiendo programar no es gran problema, solo es revisar un poco la sintaxis de cada uno. El mayor problema es que cada lenguaje tiene diferentes posibilidades así que cada lenguaje pasa a ser totalmente diferente mantiendo en común solo la lógica de los bucles y esas cosas básicas.

MySQL introdujo su lenguaje hace relativamente poco tiempo y eso se nota, esta bastante mas limitado que por ejemplo el de Oracle (pl/sql). No me peguéis pero he de decir que el lenguaje de oracle es realmente potente, solo espero que MySQL se vaya equiparando en este tema (aunque ahora que oracle es propietario de mysql no se que pasará…). Como información os diré que el lenguaje de SQL server (transact-sql) está también bastante limitado.

Condición IF

IF variable = 1 THEN
hacer algo
ELSE
lo otro
END IF;

Salvo en el caso de trabaja con null que es

IF variable IS [NOT] null

Bucles

REPEAT

[etiqueta:] REPEAT
hacer algo
UNTIL expresion (ej variable=5)
END REPEAT [etiqueta]

Lo que hace es repetir “hacer algo” hasta que se cumpla la condición del UNTIL. Lo de las etiquetas es para terminar ese REPEAT en concreto (por si no era lo suficientemente desestructurado jaja). Personalmente este tipo de iteraciones no me gustan nada. Seguramente haya más pero yo la que uso es while

WHILE

WHILE variable < 5 DO
hacer algo
SET variable = variable + 1;
END WHILE;

MANEJO DE VARIABLES

Declarar una variable

DECLARE variable TIPO DE DATO (ej, INT, VARCHAR(30)…)

Asignación

SET variable = variable2;

esto permite también asignar el resultado de una consulta (que devuelva un sólo resultado)

SET variable = (SELECT nombre FROM usuarios WHERE id=5);

CURSORES

Si nuna has trabajado con estos lenguajes los cursores son algo nuevo para ti (no tiene nada que ver con los punteros en C aviso). Los cursores sirve para ir procesando fila a fila el resultado de una consulta. Para poder usar bien un cursor necesitamos hacer uso de las (limitadas) excepciones de mysql. Este ejemplo esta basado en el de la pagina de mysql.

DECLARE CONTINUE HANDLER FOR SQLSTATE ‘02000’ SET terminado = 1;

Esto lo que va a hacer es poner la variable a 1 cuando salte la excepción 02000, que es cuando una consulta ya no devuelve más resultados. Ahora creamos el cursor. Un cursor ejecuta una consulta y va devolviendo fila a fila.

DECLARE cursor CURSOR FOR SELECT usuario,email FROM usuarios;

El proceso de uso de un cursor es:

  1. Abrir el cursor (open cursor;)
  2. Extraer información de un cursor (FETCH cursor INTO v_usuario,v_email;)
  3. Cerrar un cursor (close cursor;)

Es importante cerrar el cursor después de terminar de usarlo

Y con un bucle while vamos recorriendo todo el cursor. Seguro que has adivinado como

DECLARE terminado INT DEFAULT 0;
DECLARE v_usuario VARCHAR(30);
DECLARE v_email VARCHAR(30);
DECLARE CONTINUE HANDLER FOR SQLSTATE ‘02000’ SET terminado = 1;
DECLARE cursor CURSOR FOR SELECT usuario,email FROM usuarios;
OPEN cursor;
WHILE terminado = 0 DO
FETCH cursor INTO v_usuario,v_email;
//Hacer algo con las variables, Ej:
INSERT INTO usuariosBakcup (usuario,email) VALUES (v_usuario,v_email);
END WHILE;

Fíjate que pongo en las variables una v_ delante, eso es para diferenciar variables de palabras clave (como nombres de columnas). No es obligatorio pero si muy recomendable.

Ese trozo de código equivale al siguiente en php

$sql=”SELECT usuario,email FROM usuarios”;
$res=mysq_query($sql);
while($fila=mysql_fetch_array($res))
{
//Hacer algo con con las variables $fila[‘usuario’] y $fila[‘email’]
}

Puede parecerte más o menos complejo en un lenguaje que en otro, pero cuando te habítuas te resultan igual de fácil los dos.

Para terminar…

En cualquier parte podemos meter insert, update, delete o select (lo que concierne al DML, la manipulación de datos) pero NO se puede hacer uso de nada de DDL (definición de datos) que son create table, drop table y alter table prácticamente. Vamos, que podemos hacer con los datos lo que queramos pero con las tablas nada.

Para quien programe lenguajes con excepciones  sabrá lo útiles que son pero no voy a explicarlas ya que en MySQL pasan a ser solo avisos y no mantiene la naturaleza de una expeción. Si te interesa buscad en la página de mysql pero te llevarás una decepción te aviso.

Cuando abrimos un cursor, se bloquean las filas que estemos usando. Esto quiere decir que mientras tenemos abierto un cursor no podemos hacer ni UPDATE y DELETE ni insert. Al igual que mientras insertamos o actualizamos datos no podemos hacer SELECT. Este problema es conocido como “tablas mutantes” y se llama así  no porque se conviertan en monstruos y nos rompan la base de datos sino porque el problema se porque las tablas están “cambiando”. En el caso del cursor del ejemplo anterior podríamos hacer esto:

DECLARE terminado INT DEFAULT 0;
DECLARE v_usuario VARCHAR(30);
DECLARE v_email VARCHAR(30);
DECLARE CONTINUE HANDLER FOR SQLSTATE ‘02000’ SET terminado = 1;
DECLARE cursor CURSOR FOR SELECT usuario,email FROM usuarios;
OPEN cursor;
WHILE terminado = 0 DO
FETCH cursor INTO v_usuario,v_email;
UPDATE usuarios set usuario=v_usuario,email=v_email;
END WHILE;

Es un algoritmo totalmente idiota y sin fundamento pero nos sirve para ver eso de las tablas mutantes. Al abrir el cursor las columnas quedan bloqueadas hasta que lo cerremos (de ahí la importancia de cerrar los cursores) y mientras están bloqueadas intentamos modificar esos valores. No se puede. Pero a veces necesitamos hacer cosas de este tipo, para ello se usan tablas temporales que consiste en crear una tabla con la misma estrucutura, copiar a esa tabla temporal toda la tabla original, cerrar la tabla original y despues abrir la tabla temporal para insertar en la tabla original. Es una liada asi dicho pero vamos, es como hacer swap a un array (no se si con ese ejemplo me habrás entendido mejor).

Bueno, más o menos los principios de este lenguaje quedan dichos. Otro día veremos los PROCEDIMIENTOS, las FUNCIONES y los TRIGGERS (disparadores) que es lo que programremos con este lenguaje.

You may also like...

7 Responses

  1. paulince dice:

    No es cierto que no puedes hacer nada en un procedimiento con las tablas…puedes executar cualquier instruccion de tipo Create, alter , truncate drop a traves del comando EXEC IMMEDIATE (‘tu commando ex ALTER TABLE mitabla RENAME TO tutabla’) y puedes lanzar cuantos EXEC IMMEDIATE necesitas….

  2. Maxpowel dice:

    Intenta crear este trigger

    CREATE TRIGGER crear_tabla
    BEFORE INSERT ON tabla
    FOR EACH ROW
    BEGIN
    CREATE TABLE tabla2 ( id INT );
    END

    Suponiendo que existe una tabla llamada tabla y que la tabla2 no existe.

    Me tira este error al intentar crearlo:
    #1422 – Explicit or implicit commit is not allowed in stored function or trigger.

    Lo cual es lógico pero tienes razon en cuanto a lo de los procedimientos, me temo que los trata como bloques anónimos (donde si puedes hacer lo que te de la gana). Siempre se aprende algo, aun así soy contrario a hacer procedimientos que usen DDL que además de ser arriesgado es poco estandar.

    Gracías por tu aportación 😉

  3. LAURA dice:

    es que no puedo encontrar los ejemplos que necesito para el insert disculpas por no poder encontrar o sino queria que si fuera posible me ayuden

  4. Maskateesta dice:

    por q no puedo crear un procedimiento con insert into en SQL y me manda un chingo de errores

  5. Maxpowel dice:

    Buenas, sí se pueden poner inserts en un procedimiento así que tendrás algún fallo de sintaxis pero si no das más dellates no te puedo ayudar

  6. Héctor dice:

    Excelente mi estimado, muy buena explicación me ayudaste un monton, felicitaciones y sobretodo:

    MUCHAS GRACIAS.

  1. 14 mayo, 2009

    […] Pero como siempre que hay una limitación, se inventa algo para elminarla. … fique por dentro clique aqui. Fonte: […]

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *