MySQL: @variable vs. variable. ¿Cual es la diferencia? (Parte 2)
-
06-07-2019 - |
Pregunta
Ok, a partir de la última pregunta que hice , ¿Cómo maneja Mysql la declaración where en el siguiente código?
DELIMITER ;//
DROP PROCEDURE IF EXISTS `test`;//
CREATE PROCEDURE `test`
(
id INT
)
BEGIN
SELECT *
FROM some_table
WHERE id = id;
END;//
¿Qué hace MySQL en este caso? ¿Trata la cláusula where como
some_table.id = id
o lo trata como
some_table.id = some_table.id
En este momento estoy haciendo algo como
WHERE id = @id
porque no sabía que había variables de sesión en MySQL y no se quejaba y pensé que era una forma explícita de decir "dónde esta columna es igual a esta variable".
Algunos podrían decir "duh .. por supuesto, lo trata como column = variable " pero podría haber dicho fácilmente dónde "variable = columna". Entonces, ¿cómo maneja esto?
Solución
El esquema de nomenclatura variable de MySQL es un poco extraño, cuando se le echa un primer vistazo. Generalmente MySQL diferencia entre tres tipos de variables:
- variables del sistema ( global o < a href = "http://dev.mysql.com/doc/refman/5.0/en/server-session-variables.html" rel = "noreferrer"> sesión alcance):
@@ varname
- variables definidas por el usuario (son ámbitos de sesión ):
@varname
- variables locales almacenadas programas:
varname
Entonces, los conflictos de nombres, como los que mencionó anteriormente, solo surgen dentro de los programas almacenados. Por lo tanto, primero debe intentar evitar estos conflictos de nombres asignando nombres de parámetros inequívocos, p. prefijando los parámetros con p
como pId
. Si MySQL encuentra una ambigüedad interpretará la referencia como el nombre de una variable ( ver aquí ):
[...] Los nombres de variables locales no deben ser lo mismo que los nombres de columna. Si un SQL , como una
SELECT ... INTO
declaración, contiene una referencia a un columna y una variable local declarada con el mismo nombre, MySQL actualmente interpreta la referencia como el nombre de una variable. [...]
La redacción actualmente de alguna manera da la impresión de que este comportamiento podría cambiar en futuras versiones.
Otros consejos
Estoy bastante seguro de que @ significa que es una variable en el procedimiento, en lugar de hacer referencia a una columna de la tabla. Solo hay una columna de tabla llamada id
, por lo que en este caso no es ambigua. Si estaba haciendo una unión, entonces necesitaría ponerle el prefijo:
select *
from table1, table2
where table1.id = @id
and table2.some_field = table1.id
No importa dónde esté, la variable siempre requerirá el prefijo @, como en esta consulta:
select id, @id
from table1
el primer ID es la columna de tabla inequívoca table1.id, y el @id hace referencia a la variable de procedimiento almacenado.