在我发布的另一个问题中,有人告诉我这两者之间有区别:
@variable
和:
variable
在MySQL。他还提到MSSQL有批处理作用域,MySQL有会话作用域。有人能为我详细解释一下吗?
在MySQL中,@variable表示用户定义的变量。你可以定义你自己的。
SET @a = 'test'; SELECT @a;
在存储程序之外,没有@的variable是系统变量,您不能自己定义。
@
这个变量的作用域是整个会话。这意味着当您与数据库的连接存在时,仍然可以使用该变量。
这与MSSQL相反,在MSSQL中,变量只在当前批查询(存储过程、脚本或其他)中可用。在同一会话中的不同批处理中它将不可用。
MySQL有一个用户自定义变量 .的概念。
它们是松散类型的变量,可以在会话中的某个地方初始化,并在会话结束之前保持其值。
它们前面有一个@符号,就像这样:@var
@var
你可以用SET语句或在查询中初始化这个变量:
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,而特定于会话的变量则不是:
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(特定于会话的变量)则不会。
var2
@var2
(除了用户定义的变量,MySQL 也还有一些预定义的“系统变量”,这些“系统变量”可能是“全局变量”。例如@@global.port或"会话变量"比如@@session.sql_mode;这些“会话变量”与特定于会话的用户定义变量无关。)
@@global.port
@@session.sql_mode
MSSQL要求声明过程中的变量,并且人们使用@Variable语法(DECLARE @TEXT VARCHAR(25) = 'text')。此外,MS允许在过程中的任何块内进行声明,不像MySQL要求在顶部进行所有声明。
@Variable
DECLARE @TEXT VARCHAR(25) = 'text'
虽然很适合命令行,但我觉得在MySQL的存储过程中使用set = @variable是有风险的。没有作用域,变量存在于作用域边界之间。这类似于JavaScript中声明变量时不带var前缀,变量是全局名称空间,会产生意外的冲突和覆盖。
set = @variable
var
我希望MySQL的好心人能够在存储过程中的不同块级别上允许使用DECLARE @Variable。注意@(@号)。@符号前缀有助于将变量名与表列名分开——因为它们通常是相同的。当然,人们总是可以加一个"v"或“;l_"前缀,但是@符号是一种方便而简洁的方法,可以让变量名与您可能从中提取数据的列匹配,而不会破坏它。
DECLARE @Variable
MySQL是存储过程的新产品,它的第一个版本做得很好。很高兴看到他们从这里开始,并看到该语言的服务器端方面逐渐成熟。
原则上,我在存储过程中使用UserDefinedVariables(前面加@)。这使工作更简单,特别是当我需要在两个或多个存储过程中使用这些变量时。当我只需要一个变量在一个存储过程中,比我使用一个系统变量(没有前置@)。
优势可以在Oracle PL / SQL中看到,这些变量有3个不同的作用域:
我一直在寻找相同的设施,以将PL/SQL编写的代码移植到另一个数据库。我找到的最近的一个是Postgres。但是所有的变量都有函数作用域。
我很高兴看到MySQL中至少有这个@工具。我不认为Oracle会在PL/SQL中构建与MySQL存储过程相同的功能,因为这可能会影响Oracle数据库的销售。