Eu estou familiarizado com o MsSQL e, portanto, nunca me ocorreu a ideia de fazer uma pergunta dessas. As respostas fornecidas aqui me deram uma pista sobre algo sobre o qual eu não tinha IDÉIA !! Thx ..
Essas variáveis não são anexadas a nenhum prefixo.
A diferença entre uma variável de procedimento e uma variável definida pelo usuário específica da sessão é que a variável do procedimento é reinicializada a NULLcada vez que o procedimento é chamado, enquanto a variável específica da sessão não é:
Como você pode ver, var2(variável de procedimento) é reinicializada cada vez que o procedimento é chamado, enquanto @var2(variável específica da sessão) não é.
(Além das variáveis definidas pelo usuário, o MySQL também possui algumas "variáveis de sistema" predefinidas, que podem ser "variáveis globais", como @@global.port"variáveis de sessão", como@@session.sql_mode ; variáveis.)
Observe também que existem variáveis globais disponíveis: veja, SELECT @@version;por exemplo. Essa também é uma razão pela qual o uso DELIMITER @@não é realmente uma boa ideia.
Mchl
13
faz novas perguntas para novidades ... existe alguma diferença entre "var = var" e "var: = var" como no seu exemplo?
Confiq # 13/12
13
@confiq: não há nenhum.
Quassnoi
10
Outra pergunta para um recém-chegado. Quando é recomendado usar @vs não?
pixelfreak
73
@confiq, @Quassnoi: existe uma diferença significativa entre :=e =, e isso :=funciona como um operador de atribuição de variáveis em qualquer lugar, enquanto =apenas funciona dessa maneira em SETdeclarações e é um operador de comparação em qualquer outro lugar. Então SELECT @var = 1 + 1;vai deixar @var inalterado e retornar um booleano (1 ou 0 dependendo do valor atual de @var), enquanto SELECT @var := 1 + 1;vai mudar @var a 2, e voltar 2.
Fora dos programas armazenados, a variable, without @, é uma variável do sistema que você não pode definir por si mesmo.
O escopo desta variável é a sessão inteira. Isso significa que, embora exista sua conexão com o banco de dados, a variável ainda pode ser usada.
Isso contrasta com o MSSQL, onde a variável estará disponível apenas no lote atual de consultas (procedimento armazenado, script ou outro). Não estará disponível em um lote diferente na mesma sessão.
@ RobM, Eles são chamados de variáveis do sistema , não variáveis de sessão.
Pacerier
1
@ Pacerier: Estou lendo os documentos errado? "" "Para indicar explicitamente que uma variável é uma variável de sessão, anteceda seu nome por SESSION, @@ session. Ou @@." ""
RobM
5
@ RobM, você está lendo errado. Leia o parágrafo inteiro, não apenas o parágrafo no marcador. Simplificando, existem dois tipos de variáveis de sessão: 1) variáveis de sessão definidas pelo usuário e 2) variáveis de sessão definidas pelo sistema . Você não pode definir uma variável de sessão definida pelo usuário usando @@. Por exemplo, set@@my_var=1, set@@session.my_var=1e set session my_var=1não iria funcionar porque my_varnão é um sistema variável, enquanto que podemos fazer set@@big_tables=1, set@@session.big_tables=1e set session big_tables=1porque big_tablesé uma variável do sistema.
Pacerier
1
@GovindRai: Na resposta de Quassnoi, var2é uma variável sem @prefixo, mas não é uma variável do sistema: é uma variável de procedimento. Isso é permitido porque está em um procedimento armazenado (também conhecido como programa armazenado). Fora dos procedimentos armazenados, uma variável sem @é uma variável do sistema.
LarsH # 14/16
10
O MSSQL exige que as variáveis dentro dos procedimentos sejam DECLAREd e as pessoas usem a sintaxe @Variable (DECLARE @TEXT VARCHAR (25) = 'texto'). Além disso, o MS permite declarações dentro de qualquer bloco do procedimento, ao contrário do mySQL, que requer todos os DECLAREs na parte superior.
Embora seja bom na linha de comando, acho que usar o "set = @variable" nos procedimentos armazenados no mySQL é arriscado. Não há escopo e variáveis vivem além dos limites do escopo. É semelhante às variáveis declaradas no JavaScript sem o prefixo "var", que são o espaço de nomes global e criam colisões e substituições inesperadas.
Espero que as pessoas boas do mySQL permitam DECLARE @Variable em vários níveis de bloco dentro de um procedimento armazenado. Observe o @ (no sinal). O prefixo do sinal @ ajuda a separar os nomes das variáveis dos nomes das colunas da tabela - pois geralmente são os mesmos. Obviamente, sempre é possível adicionar um prefixo "v" ou "l_", mas o sinal @ é uma maneira prática e sucinta de fazer com que o nome da variável corresponda à coluna da qual você pode extrair os dados sem atrapalhá-los.
O MySQL é novo nos procedimentos armazenados e eles fizeram um bom trabalho em sua primeira versão. Será um prazer ver onde eles assumem a forma aqui e observar os aspectos do idioma do servidor amadurecerem.
Em princípio, eu uso UserDefinedVariables (anexado com @) em Procedimentos armazenados. Isso facilita a vida, especialmente quando eu preciso dessas variáveis em dois ou mais procedimentos armazenados. Apenas quando eu preciso de uma variável apenas dentro do ONE Stored Procedure, utilizo uma variável de sistema (sem o prefixo @).
@ Xybo: Não entendo por que o uso de variáveis em StoredProcedures deve ser arriscado. Você poderia explicar um pouco mais o "escopo" e os "limites" (para mim como um novato)?
Isso viola os princípios básicos de engenharia de software. Por favor, não escreva outra linha de código até saber exatamente o que é escopo, e por que usar variáveis globais geralmente é uma péssima idéia. Quando participei de 101 aulas de programação, lembro-me de usar um global para praticamente qualquer coisa que resultaria em um "F" automático. Existem exceções especiais, mas como regra geral - simplesmente não faça isso!
precisa saber é o seguinte
Por quê? - Variáveis @ são absolutamente comuns em todos os livros do MySQL.
Peter Peter
Claro, em um script "simples" sem chamadas de funções, procedimentos, gatilhos, etc. e se você estiver executando apenas esse script simples ou um conjunto limitado de comandos e finalizando a sessão (destruindo assim os seus globais). Nesse caso, vá em frente e use-os, se quiser. Mas NÃO os use dentro de uma função! Se você simplesmente pesquisar no Google variáveis globais ou escopo, encontrará instantaneamente um amplo suporte à ideia de que elas são universalmente desaprovadas. Aqui está um ponto de partida: wiki.c2.com/?GlobalVariablesAreBad ou para uma explicação mais geral: en.wikipedia.org/wiki/Global_variable
BuvinJ
2
No MySQL, as variáveis @ são globais. Isto é facilmente confirmado. Defina um fora de uma função e avalie-o dentro de um. Por outro lado, defina um dentro de uma função e avalie-o fora dela. Você verá que a função não protege o escopo de tal. Eles pisam nos dedos um do outro.
precisa saber é o seguinte
1
Usando a terminologia do MySQL, as @@GLOBALvariáveis são ainda mais "globais" e insidiosas. Eles atravessam sessões! @variablestêm "escopo de sessão", portanto, pelo menos eles permanecem confinados dessa maneira. No entanto, em qualquer idioma normal, é o que você chama de escopo "global" (quando eles cruzam funções, etc.). O conceito MySQL de "global" talvez deva ser chamado de "universal", na medida em que se estende além dos limites do processo que o executa. Um "global" normalmente não pode fazer isso em uma linguagem padrão, pois os processos não compartilham espaço de memória. Isso decorre da tendência persistente (vs volátil) do SQL.
Respostas:
MySQL
tem o conceito de variáveis definidas pelo usuário .São variáveis de tipo vagamente digitado que podem ser inicializadas em algum lugar da sessão e mantêm seu valor até o término da sessão.
Eles são anexados com um
@
sinal, assim:@var
Você pode inicializar essa variável com uma
SET
instrução ou dentro de uma consulta:Ao desenvolver um procedimento armazenado
MySQL
, você pode passar os parâmetros de entrada e declarar as variáveis locais:Essas variáveis não são anexadas a nenhum prefixo.
A diferença entre uma variável de procedimento e uma variável definida pelo usuário específica da sessão é que a variável do procedimento é reinicializada a
NULL
cada vez que o procedimento é chamado, enquanto a variável específica da sessão não é:Como você pode ver,
var2
(variável de procedimento) é reinicializada cada vez que o procedimento é chamado, enquanto@var2
(variável específica da sessão) não é.(Além das variáveis definidas pelo usuário, o MySQL também possui algumas "variáveis de sistema" predefinidas, que podem ser "variáveis globais", como
@@global.port
"variáveis de sessão", como@@session.sql_mode
; variáveis.)fonte
SELECT @@version;
por exemplo. Essa também é uma razão pela qual o usoDELIMITER @@
não é realmente uma boa ideia.@
vs não?:=
e=
, e isso:=
funciona como um operador de atribuição de variáveis em qualquer lugar, enquanto=
apenas funciona dessa maneira emSET
declarações e é um operador de comparação em qualquer outro lugar. EntãoSELECT @var = 1 + 1;
vai deixar @var inalterado e retornar um booleano (1 ou 0 dependendo do valor atual de @var), enquantoSELECT @var := 1 + 1;
vai mudar @var a 2, e voltar 2.No MySQL,
@variable
indica uma variável definida pelo usuário . Você pode definir o seu próprio.Fora dos programas armazenados, a
variable
, without@
, é uma variável do sistema que você não pode definir por si mesmo.O escopo desta variável é a sessão inteira. Isso significa que, embora exista sua conexão com o banco de dados, a variável ainda pode ser usada.
Isso contrasta com o MSSQL, onde a variável estará disponível apenas no lote atual de consultas (procedimento armazenado, script ou outro). Não estará disponível em um lote diferente na mesma sessão.
fonte
SET @@a = 'test';
, cf. dev.mysql.com/doc/refman/5.1/en/set-statement.html@@
. Por exemplo,set@@my_var=1
,set@@session.my_var=1
eset session my_var=1
não iria funcionar porquemy_var
não é um sistema variável, enquanto que podemos fazerset@@big_tables=1
,set@@session.big_tables=1
eset session big_tables=1
porquebig_tables
é uma variável do sistema.var2
é uma variável sem@
prefixo, mas não é uma variável do sistema: é uma variável de procedimento. Isso é permitido porque está em um procedimento armazenado (também conhecido como programa armazenado). Fora dos procedimentos armazenados, uma variável sem@
é uma variável do sistema.O MSSQL exige que as variáveis dentro dos procedimentos sejam DECLAREd e as pessoas usem a sintaxe @Variable (DECLARE @TEXT VARCHAR (25) = 'texto'). Além disso, o MS permite declarações dentro de qualquer bloco do procedimento, ao contrário do mySQL, que requer todos os DECLAREs na parte superior.
Embora seja bom na linha de comando, acho que usar o "set = @variable" nos procedimentos armazenados no mySQL é arriscado. Não há escopo e variáveis vivem além dos limites do escopo. É semelhante às variáveis declaradas no JavaScript sem o prefixo "var", que são o espaço de nomes global e criam colisões e substituições inesperadas.
Espero que as pessoas boas do mySQL permitam DECLARE @Variable em vários níveis de bloco dentro de um procedimento armazenado. Observe o @ (no sinal). O prefixo do sinal @ ajuda a separar os nomes das variáveis dos nomes das colunas da tabela - pois geralmente são os mesmos. Obviamente, sempre é possível adicionar um prefixo "v" ou "l_", mas o sinal @ é uma maneira prática e sucinta de fazer com que o nome da variável corresponda à coluna da qual você pode extrair os dados sem atrapalhá-los.
O MySQL é novo nos procedimentos armazenados e eles fizeram um bom trabalho em sua primeira versão. Será um prazer ver onde eles assumem a forma aqui e observar os aspectos do idioma do servidor amadurecerem.
fonte
Em princípio, eu uso UserDefinedVariables (anexado com @) em Procedimentos armazenados. Isso facilita a vida, especialmente quando eu preciso dessas variáveis em dois ou mais procedimentos armazenados. Apenas quando eu preciso de uma variável apenas dentro do ONE Stored Procedure, utilizo uma variável de sistema (sem o prefixo @).
@ Xybo: Não entendo por que o uso de variáveis em StoredProcedures deve ser arriscado. Você poderia explicar um pouco mais o "escopo" e os "limites" (para mim como um novato)?
fonte
@@GLOBAL
variáveis são ainda mais "globais" e insidiosas. Eles atravessam sessões!@variables
têm "escopo de sessão", portanto, pelo menos eles permanecem confinados dessa maneira. No entanto, em qualquer idioma normal, é o que você chama de escopo "global" (quando eles cruzam funções, etc.). O conceito MySQL de "global" talvez deva ser chamado de "universal", na medida em que se estende além dos limites do processo que o executa. Um "global" normalmente não pode fazer isso em uma linguagem padrão, pois os processos não compartilham espaço de memória. Isso decorre da tendência persistente (vs volátil) do SQL.