在另外一个问题中,我发布了一我的告诉我,二者之间是有区别的: sql
@variable
和: 数据库
variable
在MySQL中。 他还提到了MSSQL如何具备批处理范围,而MySQL如何具备会话范围。 有人能够为我详细说明吗? 服务器
在MySQL中, @variable
表示用户定义的变量 。 您能够定义本身的。 session
SET @a = 'test'; SELECT @a;
在存储程序以外,不带@
的variable
是系统变量 ,您没法定义本身。 ui
此变量的范围是整个会话。 这意味着,尽管您与数据库的链接存在,但仍能够使用该变量。 spa
这与MSSQL相反,在MSSQL中,变量仅在当前的查询批次(存储过程,脚本或其余)中可用。 在同一会话中,将不能以其余批次使用它。 .net
MySQL
具备用户定义变量的概念。 命令行
它们是松散类型的变量,能够在会话的某处初始化,并保持其值直到会话结束。 code
它们以@
符号开头,例如: @var
ip
您能够使用SET
语句或在查询内部初始化此变量:
SET @var = 1 SELECT @var2 := 2
在MySQL
开发存储过程时,能够传递输入参数并声明局部变量:
DELIMITER // CREATE PROCEDURE prc_test (var INT) BEGIN DECLARE var2 INT; SET var2 = 1; SELECT var2; END; // DELIMITER ;
这些变量不带任何前缀。
过程变量和特定于会话的用户定义变量之间的区别在于,每次调用过程时,过程变量都会从新初始化为NULL
,而特定于会话的变量则不会:
CREATE PROCEDURE prc_test () BEGIN DECLARE var2 INT DEFAULT 1; SET var2 = var2 + 1; SET @var2 = @var2 + 1; SELECT var2, @var2; END; SET @var2 = 1; CALL prc_test(); var2 @var2 --- --- 2 2 CALL prc_test(); var2 @var2 --- --- 2 3 CALL prc_test(); var2 @var2 --- --- 2 4
如您所见,每次调用该过程时,都会从新初始化var2
(过程变量),而@var2
(特定于会话的变量)则不会被初始化。
(除了用户定义的变量外,MySQL 还具备一些预约义的“系统变量”,能够是“全局变量”,例如@@global.port
或“会话变量”,例如@@session.sql_mode
;这些“会话变量” ”与特定于会话的用户定义变量无关。)
原则上,我在存储过程当中使用UserDefinedVariables(以@开头)。 这使工做变得更轻松,尤为是当我在两个或多个存储过程当中须要这些变量时。 只是当我仅须要一个存储过程当中的变量时,我才使用系统变量(不带@)。
@Xybo:我不明白为何在StoredProcedures中使用@variables应该会有风险。 您能简单解释一下“范围”和“边界”吗(对我来讲,这是一个新手)?
MSSQL要求过程当中的变量为DECLAREd,人们使用@Variable语法(DECLARE @TEXT VARCHAR(25)='text')。 此外,MS容许在过程的任何块中进行声明,这与mySQL不一样,mySQL要求在顶部使用全部DECLARE。
虽然在命令行上不错,但我认为在mySQL的存储过程当中使用“ set = @variable”是有风险的。 没有范围,变量跨越范围边界。 这相似于在JavaScript中声明的不带“ var”前缀的变量,这些变量将成为全局命名空间并产生意外的冲突和覆盖。
我但愿mySQL的优秀人士将容许在存储过程的各个块级别使用DECLARE @Variable。 注意@(在符号处)。 @符号前缀有助于将变量名与表列名分开-由于它们一般是相同的。 固然,老是能够添加“ v”或“ l_”前缀,可是@符号是一种方便且简洁的方法,能够使变量名与您要从中提取数据的列匹配而不会破坏数据。
MySQL是存储过程的新手,他们在第一个版本中作得很好。 很高兴看到他们在这里采用什么形式,并观察该语言在服务器端的各个方面。