Answers:
MySQL
具有用户定义变量的概念。
它们是松散类型的变量,可以在会话的某处初始化,并保持其值直到会话结束。
它们前面带有一个@
标志,如下所示:@var
您可以使用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
;这些“会话变量”与特定于会话的用户定义无关变量。)
SELECT @@version;
例如。这也是一个原因,为什么使用DELIMITER @@
并不是一个好主意。
@
vs不使用?
:=
和之间有一个明显的区别=
,那就是它:=
在任何地方都可以用作变量赋值运算符,而=
仅在SET
语句中可以那样工作,而在其他地方则是比较运算符。这样SELECT @var = 1 + 1;
会留下@var不变,并返回一个布尔值(1或0取决于@var的电流值),而SELECT @var := 1 + 1;
将@var更改为2,然后返回2
在MySQL中,@variable
表示用户定义的变量。您可以定义自己的。
SET @a = 'test';
SELECT @a;
在存储程序之外variable
,不带的@
是系统变量,您无法定义自己。
此变量的范围是整个会话。这意味着,尽管您与数据库的连接存在,但仍可以使用该变量。
这与MSSQL相反,在MSSQL中,变量仅在当前的查询批次(存储过程,脚本或其他)中可用。在同一会话中,将不能以其他批次使用它。
SET @@a = 'test';
cf。dev.mysql.com/doc/refman/5.1/en/set-statement.html
@@
。例如set@@my_var=1
,set@@session.my_var=1
和set session my_var=1
是行不通的,因为my_var
不是一个系统变量,而我们能做的set@@big_tables=1
,set@@session.big_tables=1
以及set session big_tables=1
因为big_tables
是一个系统变量。
var2
是一个没有@
前缀的变量,但它不是系统变量:它是一个过程变量。允许这样做,因为它位于存储过程(也称为存储程序)中。在存储过程之外,没有的变量@
是系统变量。
MSSQL要求过程中的变量为DECLAREd,人们使用@Variable语法(DECLARE @TEXT VARCHAR(25)='text')。而且,MS允许在过程的任何块中进行声明,这与mySQL要求在顶部的所有DECLARE不同。
虽然在命令行上不错,但我认为在mySQL的存储过程中使用“ set = @variable”是有风险的。没有作用域,变量跨越作用域边界。这类似于在JavaScript中声明的不带“ var”前缀的变量,它们随后是全局名称空间,并会产生意外的冲突和覆盖。
我希望mySQL的优秀人士将允许在存储过程的各个块级别使用DECLARE @Variable。注意@(在符号处)。@符号前缀有助于将变量名与表列名分开-因为它们通常是相同的。当然,总是可以添加“ v”或“ l_”前缀,但是@符号是一种方便且简洁的方法,可以使变量名与您要从中提取数据的列匹配而不会破坏数据。
MySQL是存储过程的新手,他们在第一个版本中做得很好。很高兴看到他们在这里采用什么形式,并观察该语言在服务器端的各个方面。
原则上,我在存储过程中使用UserDefinedVariables(以@开头)。这使工作变得更轻松,尤其是当我在两个或多个存储过程中需要这些变量时。只是当我仅需要一个存储过程中的变量时,我才使用系统变量(不带@)。
@Xybo:我不明白为什么在StoredProcedures中使用@variables应该会有风险。您能否更轻松地解释“范围”和“边界”(对我来说是新手)?
@@GLOBAL
变量更加“全局”和隐蔽。他们跨会议! @variables
具有“会话范围”,因此至少它们以这种方式保持受限。但是,在任何普通的语言中,您都称其为“全局”范围(当它们跨功能等时)。MySQL的“全局”概念应该被称为“通用”,因为它超出了运行它的进程的范围。由于进程不共享内存空间,因此“全局”通常无法使用标准语言来执行此操作。这源于SQL的持久性(相对于易变性)。