Estoy familiarizado con MsSQL, por lo que nunca pensé en hacer esa pregunta. ¡Las respuestas proporcionadas aquí me dieron pistas sobre algo sobre lo que no tenía IDEA! Thx ..
Estas variables no se anteponen con ningún prefijo.
La diferencia entre una variable de procedimiento y una variable definida por el usuario específica de sesión es que la variable de procedimiento se reinicia NULLcada vez que se llama al procedimiento, mientras que la variable específica de sesión no es:
Como puede ver, var2(variable de procedimiento) se reinicia cada vez que se llama al procedimiento, mientras que @var2(variable específica de la sesión) no.
(Además de las variables definidas por el usuario, MySQL también tiene algunas "variables del sistema" predefinidas, que pueden ser "variables globales" como @@global.port"variables de sesión" como @@session.sql_mode; estas "variables de sesión" no están relacionadas con las definidas por el usuario específicas de la sesión variables.)
También tenga en cuenta que hay variables globales disponibles: consulte, SELECT @@version;por ejemplo. Esta es también una razón por la cual usar DELIMITER @@no es realmente una buena idea.
Mchl
13
hace nuevas preguntas para los recién llegados ... ¿hay alguna diferencia entre "var = var" y "var: = var" como en su ejemplo?
confiq
13
@confiq: no hay ninguno.
Quassnoi
10
Otra pregunta para un recién llegado. ¿Cuándo se recomienda usar @vs no?
pixelfreak
73
@confiq, @Quassnoi: hay una diferencia significativa entre :=y =, y es que :=funciona como un operador de asignación variable en todas partes, mientras que =solo funciona de esa manera en las SETdeclaraciones, y es un operador de comparación en todas partes. Por SELECT @var = 1 + 1;lo tanto , dejará @var sin cambios y devolverá un valor booleano (1 o 0 según el valor actual de @var), mientras SELECT @var := 1 + 1;que cambiará @var a 2 y devolverá 2.
Fuera de los programas almacenados, a variable, sin @, es una variable del sistema , que no puede definir usted mismo.
El alcance de esta variable es toda la sesión. Eso significa que mientras exista su conexión con la base de datos, la variable aún puede usarse.
Esto está en contraste con MSSQL, donde la variable solo estará disponible en el lote actual de consultas (procedimiento almacenado, secuencia de comandos u otro). No estará disponible en un lote diferente en la misma sesión.
@RobM, se denominan variables del sistema , no variables de sesión.
Pacerier
1
@Pacerier: ¿Estoy leyendo mal los documentos? "" "Para indicar explícitamente que una variable es una variable de sesión, preceda su nombre por SESSION, @@ session. O @@." ""
RobM
55
@RobM, lo estás leyendo mal. Lea todo el párrafo, no solo el párrafo dentro de la viñeta. En pocas palabras, hay dos tipos de variables de sesión: 1) variables de sesión definidas por el usuario y 2) variables de sesión definidas por el sistema . No puede establecer una variable de sesión definida por el usuario mediante @@. Por ejemplo, set@@my_var=1, set@@session.my_var=1, y set session my_var=1que no funciona porque my_varno es un sistema de variables, mientras que nosotros podemos hacer set@@big_tables=1, set@@session.big_tables=1y set session big_tables=1porque big_tableses una variable del sistema.
Pacerier
1
@GovindRai: En la respuesta de Quassnoi, var2es una variable sin @prefijo, pero no es una variable del sistema: es una variable de procedimiento. Esto está permitido porque está en un procedimiento almacenado (también conocido como programa almacenado). Fuera de los procedimientos almacenados, una variable sin @es una variable del sistema.
LarsH
10
MSSQL requiere que las variables dentro de los procedimientos se DECLAREn y la gente use la sintaxis @Variable (DECLARE @TEXT VARCHAR (25) = 'text'). Además, MS permite declaraciones dentro de cualquier bloque en el procedimiento, a diferencia de mySQL que requiere todos los DECLAROS en la parte superior.
Si bien es bueno en la línea de comandos, creo que usar el "set = @variable" dentro de los procedimientos almacenados en mySQL es arriesgado. No hay alcance y las variables viven a través de los límites del alcance. Esto es similar a las variables en JavaScript que se declaran sin el prefijo "var", que luego son el espacio de nombres global y crean colisiones y sobrescrituras inesperadas.
Espero que las buenas personas en mySQL permitan DECLARE @Variable en varios niveles de bloque dentro de un procedimiento almacenado. Observe la @ (en el signo). El prefijo de signo @ ayuda a separar los nombres de las variables de los nombres de las columnas de la tabla, ya que a menudo son los mismos. Por supuesto, siempre se puede agregar un prefijo "v" o "l_", pero el signo @ es una forma práctica y sucinta de hacer que el nombre de la variable coincida con la columna de la que podría estar extrayendo los datos sin bloquearla.
MySQL es nuevo en los procedimientos almacenados y han hecho un buen trabajo para su primera versión. Será un placer ver dónde lo toman aquí y ver cómo maduran los aspectos del lenguaje del lado del servidor.
En principio, uso UserDefinedVariables (antepuesto con @) dentro de Procedimientos almacenados. Esto facilita la vida, especialmente cuando necesito estas variables en dos o más procedimientos almacenados. Justo cuando necesito una variable solo dentro de UN procedimiento almacenado, entonces uso una variable del sistema (sin anteponer @).
@Xybo: No entiendo por qué usar @variables en StoredProcedures debería ser riesgoso. ¿Podría explicar un poco más el "alcance" y los "límites" (para mí como un novato)?
Esto viola los principios básicos de ingeniería de software. No escriba otra línea de código hasta que sepa exactamente cuál es el alcance, y por qué usar variables globales es generalmente una idea terrible. Cuando tomé 101 clases de programación, como recuerdo, usar un global para casi cualquier cosa resultaría en una "F" automática. Hay excepciones especiales, pero como regla general, ¡simplemente no lo hagas!
BuvinJ
¿Por qué? - @Variables son absolutamente comunes en cada MySQL-Book.
Peter
Claro, en un script "plano" sin llamadas a funciones, procedimientos, disparadores, etc. y si solo va a ejecutar ese simple script o un conjunto limitado de comandos y luego finalizar la sesión (destruyendo así sus globales). En ese caso, adelante y úsalos si quieres. ¡Pero NO los use dentro de una función! Si simplemente busca en Google las variables globales o el alcance, encontrará instantáneamente un amplio respaldo para la idea de que están universalmente mal vistas. Aquí hay un punto de partida: wiki.c2.com/?GlobalVariablesAreBad o para una explicación más general: en.wikipedia.org/wiki/Global_variable
BuvinJ
2
En MySQL, @variables son globales. Esto se confirma fácilmente. Establecer uno fuera de una función y luego evaluarlo dentro de una. Por el contrario, establezca uno dentro de una función y evalúelo fuera de ella. Verá que la función no protege el alcance de la misma. Se pisan los pies el uno al otro.
BuvinJ
1
Usando la terminología de MySQL, las @@GLOBALvariables son aún más "globales" e insidiosas. ¡Cruzan sesiones! @variablestienen "alcance de sesión", por lo que al menos permanecen confinados de esa manera. Sin embargo, en cualquier lenguaje normal, eso es lo que usted llama alcance "global" (cuando cruzan funciones, etc.). El concepto MySQL de "global" quizás debería llamarse "universal", ya que se extiende más allá de los límites del proceso que lo ejecuta. Un "global" normalmente no puede hacer eso en un lenguaje estándar, ya que los procesos no comparten espacio de memoria. Esto se deriva de la tendencia persistente (vs volátil) de SQL.
Respuestas:
MySQLtiene el concepto de variables definidas por el usuario .Son variables poco escritas que pueden inicializarse en algún lugar de una sesión y mantener su valor hasta que finalice la sesión.
Están antepuestos con un
@signo, como este:@varPuede inicializar esta variable con una
SETdeclaración o dentro de una consulta:Cuando desarrolla un procedimiento almacenado en
MySQL, puede pasar los parámetros de entrada y declarar las variables locales:Estas variables no se anteponen con ningún prefijo.
La diferencia entre una variable de procedimiento y una variable definida por el usuario específica de sesión es que la variable de procedimiento se reinicia
NULLcada vez que se llama al procedimiento, mientras que la variable específica de sesión no es:Como puede ver,
var2(variable de procedimiento) se reinicia cada vez que se llama al procedimiento, mientras que@var2(variable específica de la sesión) no.(Además de las variables definidas por el usuario, MySQL también tiene algunas "variables del sistema" predefinidas, que pueden ser "variables globales" como
@@global.port"variables de sesión" como@@session.sql_mode; estas "variables de sesión" no están relacionadas con las definidas por el usuario específicas de la sesión variables.)fuente
SELECT @@version;por ejemplo. Esta es también una razón por la cual usarDELIMITER @@no es realmente una buena idea.@vs no?:=y=, y es que:=funciona como un operador de asignación variable en todas partes, mientras que=solo funciona de esa manera en lasSETdeclaraciones, y es un operador de comparación en todas partes. PorSELECT @var = 1 + 1;lo tanto , dejará @var sin cambios y devolverá un valor booleano (1 o 0 según el valor actual de @var), mientrasSELECT @var := 1 + 1;que cambiará @var a 2 y devolverá 2.En MySQL,
@variableindica una variable definida por el usuario . Puedes definir el tuyo.Fuera de los programas almacenados, a
variable, sin@, es una variable del sistema , que no puede definir usted mismo.El alcance de esta variable es toda la sesión. Eso significa que mientras exista su conexión con la base de datos, la variable aún puede usarse.
Esto está en contraste con MSSQL, donde la variable solo estará disponible en el lote actual de consultas (procedimiento almacenado, secuencia de comandos u otro). No estará disponible en un lote diferente en la misma sesión.
fuente
SET @@a = 'test';, cf. dev.mysql.com/doc/refman/5.1/en/set-statement.html@@. Por ejemplo,set@@my_var=1,set@@session.my_var=1, yset session my_var=1que no funciona porquemy_varno es un sistema de variables, mientras que nosotros podemos hacerset@@big_tables=1,set@@session.big_tables=1yset session big_tables=1porquebig_tableses una variable del sistema.var2es una variable sin@prefijo, pero no es una variable del sistema: es una variable de procedimiento. Esto está permitido porque está en un procedimiento almacenado (también conocido como programa almacenado). Fuera de los procedimientos almacenados, una variable sin@es una variable del sistema.MSSQL requiere que las variables dentro de los procedimientos se DECLAREn y la gente use la sintaxis @Variable (DECLARE @TEXT VARCHAR (25) = 'text'). Además, MS permite declaraciones dentro de cualquier bloque en el procedimiento, a diferencia de mySQL que requiere todos los DECLAROS en la parte superior.
Si bien es bueno en la línea de comandos, creo que usar el "set = @variable" dentro de los procedimientos almacenados en mySQL es arriesgado. No hay alcance y las variables viven a través de los límites del alcance. Esto es similar a las variables en JavaScript que se declaran sin el prefijo "var", que luego son el espacio de nombres global y crean colisiones y sobrescrituras inesperadas.
Espero que las buenas personas en mySQL permitan DECLARE @Variable en varios niveles de bloque dentro de un procedimiento almacenado. Observe la @ (en el signo). El prefijo de signo @ ayuda a separar los nombres de las variables de los nombres de las columnas de la tabla, ya que a menudo son los mismos. Por supuesto, siempre se puede agregar un prefijo "v" o "l_", pero el signo @ es una forma práctica y sucinta de hacer que el nombre de la variable coincida con la columna de la que podría estar extrayendo los datos sin bloquearla.
MySQL es nuevo en los procedimientos almacenados y han hecho un buen trabajo para su primera versión. Será un placer ver dónde lo toman aquí y ver cómo maduran los aspectos del lenguaje del lado del servidor.
fuente
En principio, uso UserDefinedVariables (antepuesto con @) dentro de Procedimientos almacenados. Esto facilita la vida, especialmente cuando necesito estas variables en dos o más procedimientos almacenados. Justo cuando necesito una variable solo dentro de UN procedimiento almacenado, entonces uso una variable del sistema (sin anteponer @).
@Xybo: No entiendo por qué usar @variables en StoredProcedures debería ser riesgoso. ¿Podría explicar un poco más el "alcance" y los "límites" (para mí como un novato)?
fuente
@@GLOBALvariables son aún más "globales" e insidiosas. ¡Cruzan sesiones!@variablestienen "alcance de sesión", por lo que al menos permanecen confinados de esa manera. Sin embargo, en cualquier lenguaje normal, eso es lo que usted llama alcance "global" (cuando cruzan funciones, etc.). El concepto MySQL de "global" quizás debería llamarse "universal", ya que se extiende más allá de los límites del proceso que lo ejecuta. Un "global" normalmente no puede hacer eso en un lenguaje estándar, ya que los procesos no comparten espacio de memoria. Esto se deriva de la tendencia persistente (vs volátil) de SQL.