【问题标题】:How to declare a variable in MySQL?如何在 MySQL 中声明一个变量?
【发布时间】:2012-07-30 02:03:11
【问题描述】:

如何在mysql中声明一个变量,以便我的第二个查询可以使用它?

我想写这样的东西:

SET start = 1;
SET finish = 10;

SELECT * FROM places WHERE place BETWEEN start AND finish;

【问题讨论】:

  • 别忘了您可能需要“Allow User Variables=True”。

标签: mysql sql


【解决方案1】:

MySQL中的变量主要分为三类:

  1. User-defined variables(以@为前缀):

    您可以访问任何用户定义的变量而无需声明或 初始化它。如果你引用一个没有被 初始化后,它的值为NULL,类型为字符串。

    SELECT @var_any_var_name
    

    您可以使用SETSELECT 语句初始化变量:

    SET @start = 1, @finish = 10;    
    

    SELECT @start := 1, @finish := 10;
    
    SELECT * FROM places WHERE place BETWEEN @start AND @finish;
    

    可以从一组有限的数据中为用户变量赋值 类型:整数、十进制、浮点、二进制或非二进制字符串, 或 NULL 值。

    用户定义的变量是特定于会话的。也就是说,一个用户 一个客户定义的变量不能被其他客户看到或使用 客户。

    它们可用于使用Advanced MySQL user variable techniquesSELECT 查询。

  2. Local Variables(无前缀):

    局部变量需要在声明之前使用DECLARE 访问它。

    它们可以用作局部变量和输入参数 在存储过程中:

    DELIMITER //
    
    CREATE PROCEDURE sp_test(var1 INT) 
    BEGIN   
        DECLARE start  INT unsigned DEFAULT 1;  
        DECLARE finish INT unsigned DEFAULT 10;
    
        SELECT  var1, start, finish;
    
        SELECT * FROM places WHERE place BETWEEN start AND finish; 
    END; //
    
    DELIMITER ;
    
    CALL sp_test(5);
    

    如果缺少DEFAULT 子句,则初始值为NULL

    局部变量的作用域是 BEGIN ... END 块内 它被声明了。

  3. Server System Variables(以@@为前缀):

    MySQL 服务器维护许多配置为默认值的system variables。 它们的类型可以是GLOBALSESSIONBOTH

    全局变量影响服务器的整体操作,而会话变量影响其对单个客户端连接的操作。

    要查看正在运行的服务器使用的当前值,请使用SHOW VARIABLES 语句或SELECT @@var_name

    SHOW VARIABLES LIKE '%wait_timeout%';
    
    SELECT @@sort_buffer_size;
    

    它们可以在服务器启动时使用命令行或选项文件中的选项进行设置。 它们中的大多数可以在服务器运行时使用SET GLOBALSET SESSION 动态更改:

    -- Syntax to Set value to a Global variable:
    SET GLOBAL sort_buffer_size=1000000;
    SET @@global.sort_buffer_size=1000000;
    
    -- Syntax to Set value to a Session variable:
    SET sort_buffer_size=1000000;
    SET SESSION sort_buffer_size=1000000;
    SET @@sort_buffer_size=1000000;
    SET @@local.sort_buffer_size=10000;
    

【讨论】:

  • 不知何故 = 运算符对我不起作用。当我使用:= 运算符时,它工作得很好。
  • = 运算符仅适用于 SET 子句。要在 SELECT 查询中为变量赋值,您可以使用 := 运算符,例如SELECT @start := 1
  • 您能否澄清一下这是什么意思:“无需声明用前缀@表示的用户定义会话变量”?
  • @billynoah 我假设这意味着用户定义的会话变量(以@开头)不需要显式声明;您可以立即分配给它们,就像它们已经被声明一样。
  • 您可以使用如下 select 语句的结果分配一个变量: SET @subscriptionId = (select subscriptionId from User where emailAddress='ac@tmail.com');
【解决方案2】:

设置

SET @var_name = value;     /* or */     SET @var_name := value;

运算符 =:= 都被接受


选择

SELECT col1, @var_name := col2 from tb_name WHERE "conditon";

如果找到多个记录集,只保留 col2 中的最后一个值(覆盖);

SELECT col1, col2 INTO @var_name, col3 FROM .....

在这种情况下,select 的结果不包含 col2 值


两种方法都用过

--- TRIGGER_BEFORE_INSERT --- 从计算中设置列值

...
SELECT count(*) INTO @NR FROM a_table WHERE a_condition;
SET NEW.ord_col =  IFNULL( @NR, 0 ) + 1;
...

【讨论】:

  • =:=有什么区别?
  • 我猜对于mysql SELECT 语法是必要的,以将=(比较)的含义与:=(asign)分开
  • 在某些情况下,变量中留下的值可能与返回的最后一行不对应。例如,SELECT DISTINCT IFNULL(@var:=Name,'unknown') FROM Customers ORDER BY <some non-indexed expression> LIMIT 10 似乎在 order-by 完成之前评估变量赋值,因此 @var 的返回值甚至可能与任何返回的行无关。不过,文档并没有说明在什么条件下会发生这种情况。
【解决方案3】:

使用 setselect

SET @counter := 100;
SELECT @variable_name := value;

例子:

SELECT @price := MAX(product.price)
FROM product 

【讨论】:

    【解决方案4】:

    不同类型的变量:

    • 局部变量(不以@ 为前缀)是强类型的,并且作用域仅限于声明它们的存储程序块。请注意,如DECLARE Syntax 中所述:

    DECLARE 只允许在 BEGIN ... END 复合语句中使用,并且必须位于其开头,在任何其他语句之前。

    • 用户变量(以@ 为前缀)是松散类型的,并限定在会话范围内。请注意,它们既不需要也不能声明——直接使用即可。

    因此,如果您正在定义一个存储程序并且确实需要一个“局部变量”,则需要删除 @ 字符并确保您的 DECLARE 语句位于程序块的开头。否则,要使用“用户变量”,请删除 DECLARE 语句。

    此外,您需要将查询括在括号中,以便将其作为子查询执行:

    SET @countTotal = (SELECT COUNT(*) FROM nGrams);

    否则,您可以使用 SELECT ... INTO:

    从 nGrams 中选择 COUNT(*) 到 @countTotal;

    【讨论】:

      【解决方案5】:
      • 声明: SET @a = 1;

      • 用法: INSERT INTO `t` (`c`) VALUES (@a);

      【讨论】:

      • t 用于表,c 用于列?
      • @carloswm85 是
      【解决方案6】:

      对于任何在 concat_ws 函数中使用 @variable 来获取连接值的人,不要忘记用空值重新初始化它。否则它可以为同一个会话使用旧值。

      Set @Ids = '';
      
      select 
        @Ids := concat_ws(',',@Ids,tbl.Id),
        tbl.Col1,
        ...
      from mytable tbl;
      

      【讨论】:

        【解决方案7】:

        设置值

         declare @Regione int;   
         set @Regione=(select  id from users
         where id=1) ;
         select @Regione ;
        

        【讨论】:

          猜你喜欢
          • 2014-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-28
          • 1970-01-01
          • 1970-01-01
          • 2015-08-19
          • 2020-06-21
          相关资源
          最近更新 更多