目前我正在使用 MySQL 中的存储过程,并且在某些过程中使用用户定义的变量,并且我已经看到该类型的变量在当前会话中被初始化并保持其值直到会话结束。
我也在使用类似的语句,select into @user_defined_variable
但我意识到这样做非常冒险,特别是在登录/身份验证方面。所以在这种情况下的解决方案是使用语句set @user_defined_variable
而不是select into
.
但我真的不确定使用 是否足够set
,因为这种类型的变量会在会话未完成时保持其值。
现在想象一下,服务器在使用相同的存储过程上同时收到多个请求,@user_defined_variable
在这种情况下会存在值冲突吗?例如,如果被调用的存储过程login
使用了用户定义的变量@uuidUser
,并且被调用的存储过程home
也使用了@uuidUser
,那么是否存在该home
过程使用过程@uuidUser
内部赋值的风险login
?
注意:我正在使用 Node.js,并且我只有一个与 MySQL 实例的连接,我不会为每个请求创建一个连接。所以@user_defined_variables
将永远存在。
用户定义的变量特定于设置它们的会话。他们不会泄漏到其他会话。
每个会话都有自己的变量。不同会话中的同名变量不具有相同的值。就像任何编程语言中的局部变量一样。
即使您使用连接池以便后续请求重用给定连接,当连接被回收时也会重置会话。因此,所有特定于会话的状态都被丢弃。这包括会话变量(系统变量和用户定义的变量)、临时表、事务、会话字符集、会话计数器等。如果这些东西中的任何一个泄漏到后续的重用请求中,对安全性将是非常不利的来自连接池的连接。
SELECT ... INTO @user_defined_variable
与之间在范围或安全性方面没有区别SET @user_defined_variable = ...
。两者都为该用户定义的变量赋值。该变量在会话期间保持其值,或者直到它被分配一个不同的值。在会话结束时,该变量被丢弃。如果需要,我还建议在存储过程或触发器中使用局部变量。您必须
DECLARE
在存储例程的顶部使用来创建这样的变量。局部变量的范围只是创建它的例程。在该例程返回后,局部变量将被丢弃。