lunes, 23 de noviembre de 2015

Funciones en MySQL

Una función es similar a un procedimiento almacenado pero retorna un valor. La estructura de la función en MySQL es así:

CREATE FUNCTION nombre_funcion() /* Entre los paréntesis irían los argumentos */
RETURNS TIPO_VARIABLE /* El tipo de variable que retorna, sea INT, VARCHAR, etc */
BEGIN /* Aquí comienza el juego */
DECLARE mi_variable TIPO_VARIABLE /*La variable con el mismo tipo de arriba*/
/*Ahora vamos a ejecutar las instrucciones que en este caso son un select. El comando INTO es para asignar elvalor de la consulta en la variable*/
SELECT columna_1 INTO mi_variable /* EL valor de la columna se almacena en la variable*/
FROM mi_tabla
WHERE columna_1 > 10; /*Por poner algún ejemplo*/
RETURN mi_variable; /* Devuelve el valor*/
END  /*Fin del juego*/
Vamos a hacer un ejemplo con la database ejemplo1 del tutorial anterior y la tabla ejemplo. Recordemos que habíamos guardado dos registros. Vamos a contar los nombres para saber cuántos registros hay.
Nuestra tabla es así:


Ahora creamos la función en la misma terminal. Recuerden crear un delimitador antes de empezar:



 Y por último probamos que funcione. Como yo tengo dos registros en mi tabla (Carlos y Natalia), me debe retornar 2:




domingo, 22 de noviembre de 2015

Procedimientos almacenados (Parte 2): Select y cursores con Oracle

Aquí me estoy metiendo en camisas de once varas porque de este tema sólo se lo que aprendí entre ayer y hoy. Pero la idea es que estos apuntes me saquen de líos en algún momento y de paso, tal vez, sirvan como guía a alguien.
La primera sorpresa que me llevé fue que con los procedimientos almacenados un select no es tan sencillo como un insert. Hay que usar cursores para realizarlo, al menos en Oracle. MySQL sí que permite hacer un select en un procedimiento, por lo que de momento no necesito un cursor en MySQL y dejaré ese tema para más adelante.
¿Qué es un cursor? Pues si no entendí mal es una herramienta para recorrer datos cuando necesitamos varios de ellos en una sola consulta. Parecido a un ciclo donde interamos sobre una matriz en programación.
La explicación no es la mejor pero pueden encontrar mucha información en estos enlaces:

http://www.techonthenet.com/oracle/cursors/declare.php
http://stackoverflow.com/questions/1170548/get-resultset-from-oracle-stored-procedure
http://stackoverflow.com/questions/3535405/execute-an-oracle-function-that-returns-a-reference-cursor-in-c-sharp
http://elbauldelprogramador.com/plsql-cursores/
http://www.desarrolloweb.com/articulos/cursores-pl-sql-I.html
https://es.wikibooks.org/wiki/Oracle/PL/SQL/Cursores

Los últimos son en español si te preocupa el idioma :)

Vamos a volver en Oracle a nuestra base de datos ejemplo1 y vamos a crear la tabla mascota (Lo siento, no se me ocurrió otra cosa). Esta tabla tiene dos columnas: amo que será una clave foránea y se corresponde con el nombre de la persona en la tabla ejemplo, nombre_mascota y tipo_mascota que definen la mascota que corresponde a cada amo.



Una vez hemos creado la segunda tabla le insertamos algunos datos desde terminal o por la interfaz web, como prefieras. Si no sabes cómo mira el tutorial anterior:

(Sí, Natalia tiene un rinoceronte llamado Mimosín :P ).


Ahora que tenemos dos tablas para trabajar, vamos a crear un procedimiento almacenado que nos muestre el amo con la edad y el nombre de la mascota.
Para eso vamos a necesitar un cursor y yo les voy a mostrar la forma que conozco yo de momento para hacerlo en Oracle, pero no es la única. Nuevamente les remito a los enlaces de arriba.

La sintaxis sería esta (He puesto unos signos -- con notas aclaratorias):

create or replace procedure "amos_mascotas" --Nombre del procedimiento
is
cursor curs is  --curs es el nombre del cursor. Pueden poner cualquiera.
select nombre, edad, nombre_mascota -- Los datos que queremos ver 
from ejemplo join mascota --Las tablas que unimos con join
on nombre = amo; --on es lo mismo que where :)
begin -- Aquí comienza el procedimiento almacenado
for resultado in curs loop --Resultado es el iterador
dbms_output.put_line ('Nombre: '|| resultado.nombre ||' Edad: '|| resultado.edad ||'  Mascota: '|| resultado.nombre_mascota);
end loop; --Aquí termina de iterar
end;

¨Una forma de crearlo es yendo a create, procedure y desmarcar la opción include arguments. En la ventana que nos queda colocamos:

Podemos ejecutarlo en terminal usando execute o en la interfaz web poniendo el procedimiento entre begin y end, nuevamente si no sabes de qué hablo debes ir al tutorial anterior.

El resultado es este:




Y eso es todo con Oracle, para MySQL no necesitamos tanto lío para hacer un select  así que el tutorial anterior les sirve. Más adelante cuando la base esté conectada a un programa sí que vamos a necesitar cursores en MySQL para iterar línea por línea los registros.






sábado, 21 de noviembre de 2015

Procedimientos almacenados (Parte 1)

El procedimiento almacenado es un código que se almacena y ejecuta directamente en la base de datos, por lo que accede directamente a la información y por tanto resuelve más rápidamente la petición.
Los ejercicios del laboratorio 13 deben realizarse en Oracle y en MySQL y aunque ambos están basados en el estándar de lenguaje SQL cada uno tiene sus particularidades (Especialmente Oracle con PL/SQL).
Un procedimiento almacenado sencillo es el que se realiza para agilizar la inserción de datos

En MySQL: Creamos primero la base de datos ejemplo1 y le añadimos una tabla con dos columnas (nombre y edad).

Como pueden ver metí la pata e intenté crear la tabla sin haber especificado que database iba a usar :)

Una vez creada la tabla donde vamos a insertar datos mediante un procedimiento almacenado podemos crear el procedimiento.
Vamos a darle argumentos, los cuales deben ser del mismo tipo que los valores de la tabla y además serán argumentos de entrada.
Primero colocamos un delimitador, que puede ser el símbolo que nos de la gana aunque suele usarse // o $$. SI no ponemos eso al dar enter se va a ejecutar donde vea un ";" aunque no hayamos terminado con nuestro procedure.
Create procedure insertar_ejemplo le dice a MySQL que quiero crear un PA con ese nombre. Luego pongo los argumentos que pueden tener el nombre que quieras pero respetar los tipos de las columnas que quieres insertar.
Begin marca dónde comienzan las instrucciones. Dentro de begin y antes del end colocamos el código que debe ejecutarse.
Normalmente para insertar datos hacemos un insert into mi_tabla(columna_1, columna_2...) y en values ponemos entre paréntesis los datos que queremos insertar. En este caso en values pondremos los parámetros. Quedaría así:


Ese sería nuestro procedure ya listo para uso mediante el comando call. Lo llamamos y le damos argumentos:


Y como pueden ver al hacer un select, el procedimiento ha almacenado la información.

Ahora toca hacer lo mismo con Oracle. Ya les digo que si lo hacen en la interfaz web de Oracle y si lo hacen en la terminal, el proceso es igual. Pero el llamado del procedimiento sí que es distinto.

En Oracle la terminal no me parece tan amistosa como la de MySQL, por lo que me voy a la interfaz web Get Started.

Creamos un nuevo workspace que en este caso llamé nuevamente ejemplo 1 y en el creamos nuevamente nuestra tabla ejemplo con sus columnas nombre y edad. Para el caso no hace falta crearle clave primaria y desde luego no lleva foráneas ya que no hay más tablas, pero deben crearle la clave primaria porque nos servirá en el próximo ejercicio. La clave primaria sera nombre.


Una vez que hayas creado tu tabla (No expliqué eso en detalle porque supongo que esa parte sabes hacerla si estás aquí, pero cualquier cosa pregunta), vamos nuevamente a la opción create y esta vez no escogemos table sino procedure. Le daré el mismo nombre al procedimiento y a los argumentos que en el ejemplo con MySQL. Si quieres hacerlo en MySQL en una interfaz amigable como la de la aplicación de Oracle puedes usar MySQL workbench y verás que es muy parecido.




Ahora escribimos nuestro procedimiento. Oracle creará automáticamente el delimitador, el begin, el end y todo lo demás así que sólo dale el insert con los argumentos.

Tú sólo le das las sentencias que van entre el begin  el end.


El crea el procedimiento con la sintaxis correcta.

El llamado desde la interfaz web de oracle se hace así:


Si haces el llamado desde la terminal se usa el comando execute:


Ahí están los dos datos. El que metí por la intefaz web y el que hice por terminal.

No olvides salir tecleando exit en la terminal para que se guarden los datos. Si cierras la terminal sin hacerlo no se guardará la inserción de datos o lo que hayas hecho (Yo aprendí a las malas jejeje).
Espero que le sirva a alguien y más adelante publicaré otro tutorial sobre procedures, funciones, triggers, etc.