在我发布的另一个问题中,有人告诉我,之间有区别:
@variable
和
variable
在MySQL中。他还提到了MSSQL如何具有批量作用域以及MySQL具有会话作用域。有人可以为我详细说明这个吗?
答案 0 :(得分:601)
MySQL
具有 user-defined variables 的概念。
它们是松散类型的变量,可以在会话中的某处初始化,并保持其值直到会话结束。
它们前面带有@
符号,如下所示:@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
;这些“会话变量”与特定于会话的用户定义变量无关。)
答案 1 :(得分:69)
在MySQL中,@variable
表示user-defined variable。您可以定义自己的。
SET @a = 'test';
SELECT @a;
在存储的程序之外,没有variable
的{{1}}是system variable,您无法自行定义。
此变量的范围是整个会话。这意味着当您与数据库的连接存在时,仍然可以使用该变量。
这与MSSQL形成对比,在MSSQL中,变量仅在当前批次的查询(存储过程,脚本或其他)中可用。它不会在同一会话中以不同的批次提供。
答案 2 :(得分:10)
MSSQL要求程序中的变量为DECLAREd,并且人们使用@Variable语法(DECLARE @TEXT VARCHAR(25)='text')。此外,MS允许在过程中的任何块内声明,不像mySQL需要顶部的所有DECLARE。
虽然在命令行上很好,但我觉得在mySQL中的存储过程中使用“set = @variable”是有风险的。跨范围边界没有范围和变量。这与声明没有“var”前缀的JavaScript中的变量类似,后者是全局命名空间并创建意外的冲突和覆盖。
我希望mySQL的优秀人员能够在存储过程中的各个块级别允许DECLARE @Variable。注意@(在标志处)。 @符号前缀有助于将变量名称与表列名分开 - 因为它们通常是相同的。当然,总是可以添加“v”或“l_”前缀,但是@符号是一种方便而简洁的方法,可以使变量名称与您可能从中提取数据的列匹配而不会破坏它。
MySQL是存储过程的新手,他们在第一个版本上做得很好。很高兴看到他们在这里采用它的形式,并观察语言服务器方面的成熟。
答案 3 :(得分:3)
原则上,我在存储过程中使用UserDefinedVariables(前缀为@)。这使生活更轻松,特别是当我在两个或更多存储过程中需要这些变量时。就在我只需要一个存储过程中的变量时,我使用系统变量(没有前置@)。
@Xybo: 我不明白为什么在StoredProcedures中使用@variables会有风险。你能解释一下"范围"和"边界"有点容易(对我来说是一个新人)?
答案 4 :(得分:0)
@variable
非常有用。
有些情况下,变量值是在第一次调用中创建的,并且在后续调用的函数中需要。
优势可以在 Oracle PL/SQL 中看出,其中这些变量具有 3 个不同的范围:
我开发了一种架构,其中完整的代码是用 PL/SQL 编写的。这些是从用 Java 编写的中间件调用的。有两种类型的中间件。一种用于满足同样用 Java 编写的客户端的调用。另一个用于满足来自浏览器的调用。 客户端工具 100% 是用 JavaScript 实现的。使用命令集代替 HTML 和 JavaScript 来编写 PL/SQL 中的应用程序。
我一直在寻找将用 PL/SQL 编写的代码移植到另一个数据库的相同工具。我找到的最接近的一个是 Postgres。但是所有的变量都有函数作用域。
@
的看法我很高兴看到 MySQL 中至少有这个 @
工具。我认为 Oracle 不会在 PL/SQL 中构建与 MySQL 存储过程相同的工具,因为它可能会影响 Oracle 数据库的销售。