MySQL: @variable vs. variabile. Qual è la differenza? (Parte 2)
-
06-07-2019 - |
Domanda
Ok, costruendo l'ultima domanda che ho posto , In che modo Mysql gestisce la dichiarazione where nel seguente codice:
DELIMITER ;//
DROP PROCEDURE IF EXISTS `test`;//
CREATE PROCEDURE `test`
(
id INT
)
BEGIN
SELECT *
FROM some_table
WHERE id = id;
END;//
Cosa fa MySQL in questo caso? Tratta la clausola where come
some_table.id = id
o lo tratta come
some_table.id = some_table.id
In questo momento sto facendo qualcosa del genere
WHERE id = @id
perché non sapevo che c'erano variabili di sessione in MySQL e non si lamentava e pensavo che fosse un modo esplicito di dire "dove questa colonna è uguale a questa variabile".
Alcuni potrebbero dire " duh .. ovviamente lo tratta come colonna = variabile " ma avrei potuto facilmente dire dove " variabile = colonna. " Quindi, come gestisce questo?
Soluzione
Lo schema di denominazione delle variabili di MySQL è un po 'strano, quando lo guardiamo per la prima volta. Generalmente MySQL distingue tre tipi di variabili:
- variabili di sistema ( global o < a href = "http://dev.mysql.com/doc/refman/5.0/en/server-session-variables.html" rel = "noreferrer"> sessione con ambito):
@@ varname
- variabili definite dall'utente (sono nell'ambito della sessione ):
@varname
- local variabili archiviate programmi:
varname
Quindi conflitti di denominazione, come quelli che hai menzionato sopra, sorgono solo all'interno di programmi memorizzati. Pertanto, dovresti prima cercare di evitare questi conflitti di denominazione assegnando nomi di parametri non ambigui, ad es. prefissando i parametri con p
come pId
. Se MySQL incontra un'ambiguità interpreterà il riferimento come il nome di una variabile ( vedi qui ):
[...] I nomi delle variabili locali non dovrebbero essere uguale ai nomi delle colonne. Se un SQL , ad esempio un
SELECT ... INTO
istruzione, contiene un riferimento a colonna e una variabile locale dichiarata con lo stesso nome, MySQL al momento interpreta il riferimento come il nome di una variabile. [...]
La formulazione attualmente dà in qualche modo l'impressione che questo comportamento potrebbe cambiare nelle versioni future.
Altri suggerimenti
Sono abbastanza sicuro che @ indica che si tratta di una variabile nella procedura, anziché fare riferimento a una colonna della tabella. Esiste solo una colonna della tabella denominata id
, quindi in questo caso non è ambigua. Se stavi facendo un join, allora dovresti prefissarlo:
select *
from table1, table2
where table1.id = @id
and table2.some_field = table1.id
Non importa dove si trovi, la variabile richiederà sempre il prefisso @, come in questa query:
select id, @id
from table1
il primo id è la colonna di tabella non ambigua table1.id e @id fa riferimento alla variabile della procedura memorizzata.