MySQL: variável vs @variable. Qual é a diferença? (Parte 2)
-
06-07-2019 - |
Pergunta
Ok, construindo fora a última pergunta que fiz , como é que Mysql lidar com o que statment no código a seguir:
DELIMITER ;//
DROP PROCEDURE IF EXISTS `test`;//
CREATE PROCEDURE `test`
(
id INT
)
BEGIN
SELECT *
FROM some_table
WHERE id = id;
END;//
O que MySQL fazer neste caso? Será que tratar a cláusula onde, como
some_table.id = id
ou será que tratá-lo como
some_table.id = some_table.id
Agora eu estou fazendo algo parecido
WHERE id = @id
porque eu não sabia que havia variáveis ??de sessão em MySQL e não reclamar e eu pensei que era uma maneira explícita de dizer "onde esta coluna é igual a esta variável".
Alguns poderiam dizer "duh .. é claro que trata-lo como coluna = variável", mas eu poderia facilmente ter dito que "variable = coluna." Então como é que lidar com isso?
Solução
esquema de nomeação variável do MySQL é um pouco estranho, ao ter o primeiro olhar para ele. diferencia geralmente MySQL entre três tipos de variáveis:
- variáveis ??do sistema ( global ou < a href = "http://dev.mysql.com/doc/refman/5.0/en/server-session-variables.html" rel = "noreferrer"> sessão escopo):
@@varname
- definido pelo usuário variáveis ??(eles são escopo sessão ):
@varname
- variáveis ?? locais armazenados programas:
varname
conflitos Então nomeação, como aqueles que você mencionou acima, só surgem dentro de programas armazenados. Portanto, você primeiro deve tentar evitar esses conflitos de nomeação através da atribuição de nomes de parâmetros inequívoca, por exemplo, por prefxing os parâmetros com p
tais como pId
. Se o MySQL encontra um ambigüidade ele irá interpretar a referência como o nome de uma variável ( veja aqui ):
[...] nomes de variáveis ??locais não devem ser o mesmo que os nomes das colunas. Se um SQL declaração, como um
SELECT ... INTO
declaração, contém uma referência a um coluna e uma variável local declarada com o mesmo nome, MySQL atualmente interpreta a referência como o nome de uma variável. [...]
O texto atualmente de alguma forma dá a impressão de que esse comportamento pode mudar em versões futuras.
Outras dicas
Eu tenho certeza que as @ significa que é uma variável no procedimento, em vez de fazer referência a uma coluna da tabela. Há apenas uma coluna tabela com o nome id
, portanto, neste caso, é inequívoca. Se você estivesse fazendo uma junção, então você precisa prefixar-lo:
select *
from table1, table2
where table1.id = @id
and table2.some_field = table1.id
Não importa onde ele está, a variável exigirá sempre o prefixo @, como em esta consulta:
select id, @id
from table1
o primeiro id é o table1.id coluna da tabela inequívoca, e as referências @Id a variável de procedimento armazenado.