MySQL: @ variable vs variable. Quelle est la différence? (Partie 2)
-
06-07-2019 - |
Question
D'accord, à partir de la dernière question que j'ai posée , Comment Mysql gère-t-il la déclaration where dans le code suivant:
DELIMITER ;//
DROP PROCEDURE IF EXISTS `test`;//
CREATE PROCEDURE `test`
(
id INT
)
BEGIN
SELECT *
FROM some_table
WHERE id = id;
END;//
Que fait MySQL dans ce cas? Traite-t-il la clause where comme
some_table.id = id
ou le traite-t-il comme
some_table.id = some_table.id
En ce moment je fais quelque chose comme
WHERE id = @id
parce que je ne savais pas qu'il y avait des variables de session dans MySQL, cela ne s'est pas plaint et je pensais que c'était une façon explicite de dire "où cette colonne est égale à cette variable".
Certains pourraient dire "duh .., bien sûr, il le traite comme une colonne = variable". mais j’aurais facilement pu dire où " variable = colonne. " Alors, comment gère-t-il cela?
La solution
Le schéma de nommage des variables de MySQL est un peu bizarre quand on le regarde pour la première fois. De manière générale, MySQL distingue trois types de variables:
- variables système ( global ou < a href = "http://dev.mysql.com/doc/refman/5.0/en/server-session-variables.html" rel = "noreferrer"> session (étendue):
@@ nom_var
- variables définies par l'utilisateur (elles sont limitées à la session) ):
@varname
- variables locales stockées programmes:
nomvar
Ainsi, les conflits de noms, tels que ceux que vous avez mentionnés ci-dessus, ne surviennent que dans les programmes stockés. Par conséquent, vous devez d’abord essayer d’éviter ces conflits de noms en attribuant des noms de paramètres non ambigus, par exemple. en préfixant les paramètres avec p
tel que pId
. Si MySQL rencontre une ambiguïté , il interprétera la référence comme le nom d'une variable ( voir ici ):
[...] Les noms de variables locales ne doivent pas être identique aux noms de colonnes. Si un SQL telle qu'une instruction
SELECT ... INTO
déclaration, contient une référence à un colonne et une variable locale déclarée avec le même nom, MySQL actuellement interprète la référence comme nom d'une variable. [...]
La formulation actuellement donne en quelque sorte l’impression que ce comportement pourrait changer dans les versions futures.
Autres conseils
Je suis presque sûr que le @ signifie qu'il s'agit d'une variable dans la procédure, plutôt que de référencer une colonne de table. Il n'y a qu'une seule colonne de table nommée id
. Dans ce cas, elle est donc sans ambiguïté. Si vous faites une jointure, vous devrez alors la préfixer:
select *
from table1, table2
where table1.id = @id
and table2.some_field = table1.id
Peu importe où il se trouve, la variable nécessitera toujours le préfixe @, comme dans cette requête:
select id, @id
from table1
le premier identifiant est la colonne non ambiguë de table table1.id, et le @id fait référence à la variable de procédure stockée.