MySQL: @variable vs. variable。有什么不同?

在我发布的另一个问题中,有人告诉我这两者之间有区别:

@variable

和:

variable

在MySQL。他还提到MSSQL有批处理作用域,MySQL有会话作用域。有人能为我详细解释一下吗?

444151 次浏览

在MySQL中,@variable表示用户定义的变量。你可以定义你自己的。

SET @a = 'test';
SELECT @a;

在存储程序之外,没有@variable系统变量,您不能自己定义。

这个变量的作用域是整个会话。这意味着当您与数据库的连接存在时,仍然可以使用该变量。

这与MSSQL相反,在MSSQL中,变量只在当前批查询(存储过程、脚本或其他)中可用。在同一会话中的不同批处理中它将不可用。

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;这些“会话变量”与特定于会话的用户定义变量无关。)

MSSQL要求声明过程中的变量,并且人们使用@Variable语法(DECLARE @TEXT VARCHAR(25) = 'text')。此外,MS允许在过程中的任何块内进行声明,不像MySQL要求在顶部进行所有声明。

虽然很适合命令行,但我觉得在MySQL的存储过程中使用set = @variable是有风险的。没有作用域,变量存在于作用域边界之间。这类似于JavaScript中声明变量时不带var前缀,变量是全局名称空间,会产生意外的冲突和覆盖。

我希望MySQL的好心人能够在存储过程中的不同块级别上允许使用DECLARE @Variable。注意@(@号)。@符号前缀有助于将变量名与表列名分开——因为它们通常是相同的。当然,人们总是可以加一个"v"或“;l_"前缀,但是@符号是一种方便而简洁的方法,可以让变量名与您可能从中提取数据的列匹配,而不会破坏它。

MySQL是存储过程的新产品,它的第一个版本做得很好。很高兴看到他们从这里开始,并看到该语言的服务器端方面逐渐成熟。

原则上,我在存储过程中使用UserDefinedVariables(前面加@)。这使工作更简单,特别是当我需要在两个或多个存储过程中使用这些变量时。当我只需要一个变量在一个存储过程中,比我使用一个系统变量(没有前置@)。

< p > @Xybo: 我不明白为什么在存储过程中使用@variables是有风险的。你能更简单地解释一下“范围”和“界限”吗(对我这个新手来说)?< / p >
如果从Java、Python等编写的应用程序中调用存储过程@variable非常有用。 在某些情况下,变量值在第一次调用中创建,并在后续调用的函数中需要

PL/SQL (Oracle)简介

优势可以在Oracle PL / SQL中看到,这些变量有3个不同的作用域:

  • 函数退出时范围结束的函数变量
  • 包体变量定义在包的顶部和所有范围为会话且可见性为包的函数之外。
  • 包变量,其变量为session,可见性为全局。

我的PL/SQL经验

我已经开发了一个体系结构,其中完整的代码是用PL/SQL编写的。这些调用来自Java编写的中间件。中间件有两种类型。一个用于满足来自客户端的调用,也是用Java编写的。另一个则用于处理来自浏览器的调用。 客户机设施100%用JavaScript实现。在PL/SQL中使用命令集来代替HTML和JavaScript来编写应用程序

我一直在寻找相同的设施,以将PL/SQL编写的代码移植到另一个数据库。我找到的最近的一个是Postgres。但是所有的变量都有函数作用域。

对MySQL中@的意见

我很高兴看到MySQL中至少有这个@工具。我不认为Oracle会在PL/SQL中构建与MySQL存储过程相同的功能,因为这可能会影响Oracle数据库的销售。