BD UD7 Variables

De MediaWiki
Ir a la navegación Ir a la búsqueda

Introducción

Nota: Todos los ejemplos están basados en esta base de datos.

Como en cualquier otro lenguaje de programación vamos a tener la posibilidad de emplear variables. La diferencia con respeto de los ‘lenguajes tradicionales’ es que podemos emplear dichas variables para guardar resultados de consultas SQL o emplearlos como datos a enviar a órdenes SQL como INSERT, UPDATE,....

En MYSQL tenemos que considerar dos casos cuando empleamos variables:

  • Las empleamos con un conjunto de instrucciones que guardaremos en un archivo con extensión .sql
  • Las empleamos dentro de un procedimiento almacenado, función o trigger.



Variables en ficheros de código SQL

  • Nota: Indicar que, como comenté antes, este punto no hace referencia a los bloques de código anónimo que se pueden crear en otros gestores de bases de datos relacional.
En este punto hago referencia sobre todo, a los archivos .sql que podemos guardar en disco y que no se guardan internamente en el gestor como pasa con los procedimientos almacenados y funciones.

Las variables usadas:

  • No son necesario declararlas y las podemos emplearlas directamente.
  • Empiezan con el símbolo @
  • Para asignarles un valor empleamos la orden SET o INTO
  • A estas variables se les denomina variables de sesión. Significa que son variables que se pueden acceder desde cualquier parte (procedimiento, función,...vienen a ser como variables globales en la programación tradicional) y tendrán un valor diferente en sesiones diferentes, entendiéndose una sesión como una conexión a Mysql. Lo veremos posteriormente.

Veamos un ejemplo:

Mod BD Prog Variables 1.jpg
Como podéis comprobar, la variable de nombre @nombre tiene de valor ‘Pepe’.

Podemos emplear variables para guardar información de una orden SQL, pero debemos asegurarnos que solamente devuelve una fila. En este caso empleamos la cláusula INTO dentro del SELECT:

Mod BD Prog Variables 2.jpg

En este caso estamos empleando la variable @anhos en la que guardamos los años de un animal.

Podemos emplear varias variables a la vez:

Mod BD Prog Variables 3.jpg

Fijarse como el INTO lleva dos variables. Cada columna del select (y en el orden en el que se encuentran) se va a corresponder con una variable del INTO (en el mismo orden que el select). El número de columnas y variables debe de ser la misma.


Podemos hacer uso de las funciones integradas del gestor para realizar cualquier modificación sobre los datos de las variables y después emplearlas en otras instrucciones SQL:

Mod BD Prog Variables 4.jpg

O por ejemplo:

Mod BD Prog Variables 5.jpg

Podemos emplear variables en cualquier orden SQL, no tiene por qué ser solo SELECT:

Mod BD Prog Variables 6.jpg

Fijarse que si este bloque de código lo ejecutáis dos veces, dará un error. Esto es debido a que las variables con @ son variables de sesión.

Este tipo de variables, que no llevan un tipo de dato asociado (son débilmente tipadas), su valor es visible en todas las pestañas que abráis de tipo SQL dentro de la sesión en la que estáis conectados.

Es decir, si abrís otra pestaña SQL y ejecutáis la orden:

Mod BD Prog Variables 7.jpg


Os saldrá el nombre del animal que guardasteis en la consulta anterior. Tendríais que abrir otra sesión, es decir, otra conexión a Mysql:

Mod BD Prog Variables 8.jpg

para comprobar que esa variable ya no tiene el valor asignado.


La explicación de por qué os da un error al ejecutar estas órdenes dos veces:

1 SELECT nombre
2 INTO @nombreAnimalSinArtista
3 FROM ANIMALES
4 WHERE nombre NOT IN (SELECT nombre_animal
5                      		        FROM ANIMALES_ARTISTAS)
6 LIMIT 1;                     
7                      
8 INSERT INTO ANIMALES_ARTISTAS
9 VALUES (@nombreAnimalSinArtista,'11111111A');

La primera orden SQL (la del SELECT) no devuelve nada (ya que no encuentra otro animal que no esté cuidado por un artista). Por lo tanto nunca se ejecuta la cláusula INTO y por lo tanto la variable @nombreAnimalSinArtista sigue guardando el valor anterior y por eso da un error de clave duplicada en el INSERT.


Las variables de sesión tienen que cumplir las siguientes características:

  • Comenzar su nombre con el símbolo @, por ejemplo: @nombre
  • Puede incluír cualquier carácter alfanumérico.
  • Puede incluír los símbolos: ".", "_", "$"
  • Puede incluír otro tipo de símbolos (incluído espacio en blanco) a condición de que se escriba el nombre de la variable entre comillas: @'my var', @'my-var', @"my-var", or @'my-var'.
  • No se distingue mayúsculas de minúsculas
  • Longitud máxima: 64 caracteres.


Indicar que las variables que empiezan por @@ son variables del sistema que dependiendo del ‘scope’ que tengan, pueden ser globales o de sesión. Las variables que son globales tienen el mismo valor en todas las sesiones de todos los usuarios. Por ejemplo, en el tema de transacciones vimos que para iniciar una transacción, una opción era emplear la variable del sistema autocommit:

Mod BD Prog Variables 9.jpg

Como se puede ver (opción Scope) esta variable puede ser Global o de Sesión. Para cambiar su valor podemos poner:

  • SET SESSION autocommit = 0; -- Cambia su valor en la sesión actual.
  • SET GLOBAL autocommit = 0; -- Cambia su valor a nivel global.

Más información sobre las variables del sistema: https://wiki.cifprodolfoucha.es/index.php?title=Mysql_Instalaci%C3%B3n#Variables_del_sistema



Variables locales dentro de un procedimiento, función o trigger

Nota: Indicar que las variables anteriores (las de sesión) pueden emplearse en cualquier sitio, incluído dentro de procedimientos almacenados, pero no es lo habitual.


Tenemos que ver como se crea un procedimiento almacenado, función o trigger. Dentro de ellos, las variables se definen haciendo uso de la orden DECLARE de la forma:

1 DECLARE nombreVar tipoDato [default valor_por_defecto]
Mirar el enlace anterior para ver la sintaxis completa.


A diferencia de las variables usada en los bloques de código SQL:

  • El nombre de las variables no empieza por @
  • Se debe declarar un tipo asociado a la variable pero esto no impide que puedas asignarle un dato que no se corresponde con el tipo, haciendo la conversión (siempre que pueda, como por ejemplo, asignar a una variable de cadena un valor numérico, pero no se podría a la inversa, es decir, asignar un valor de cadena a una variable definida como numérica).
  • Si no se inicializan, el valor de dichas variables por defecto es null.

Por ejemplo:

1 DECLARE numDepts int default 0;

Estamos declarando una variable de nombre numDetps, de tipo int y con valor por defecto de 0 (recordar que si no se pone default, el valor por defecto es null).

Podemos asignar un valor a una variable con el comando SET o INTO de alguna de las siguientes formas:

  • SET variable := valor;
  • SET variable = valor;
  • SELECT count(*)
INTO numDepts
FROM DEPARTAMENTOS

A diferencia de las variables de sesión, estas variables son locales al procedimiento, función o trigger donde estén definidas.

Los tipos de datos que podemos emplear son los mismos que empleamos para crear las columnas de las tablas. Podéis consultarlos en este enlace.


Aunque no existe una norma que indique como llamar a las variables, os recomiendo seguir la siguiente:

  • A las variables locales, definirlas con el prefijo: v_nombreVariable tipo



IMPORTANTE: Cuando declaremos variables locales, debemos de tener en cuenta lo siguiente si las vamos a emplear con sentencias SQL:

  • No declarar nombre de variables que coincidan con nombres de columnas. Darles un nombre diferente.
  • Si empleamos la variable para guardar el resultado de una consulta o la vamos a emplear como dato para realizar un INSERT, UPDATE o DELETE, debemos de declararla con el mismo tipo y tamaño que la columna a la que va a hacer referencia en la orden SQL. Así, si quiero guardar el nombre de un animal con SELECT INTO en una variable, dicha variable debería estar declarada como varchar(50) que es el tipo de dato y tamaño de la columna nombre de la tabla ANIMALES.




Enlace a la página principal de la UD7

Enlace a la página principal del curso




-- Ángel D. Fernández González -- (2020).