• 首页
  • css3教程
  • html5教程
  • jQuery手册
  • vue手册
  • php手册
  • MySQL手册
  • apache手册
  • redis手册
  • 用户定义的变量

    您可以在一个语句中将值存储在用户定义的变量中,稍后在另一条语句中引用它。这使您可以将值从一个语句传递到另一个语句。

    用户变量被写成,其中变量名组成的字母数字字符,,,和。如果引用它作为一个字符串或标识符(例如,用户的变量名可以包含其他字符,或)。@var_namevar_name._$@'my-var'@"my-var"@`my-var`

    用户定义的变量是特定于会话的。一个客户端定义的用户变量不能被其他客户端看到或使用。(例外:有权访问“性能模式”user_variables_by_thread表的用户可以参见所有会话的所有用户变量。)当给定的客户端会话退出时,该客户端会话的所有变量将自动释放。

    用户变量名称不区分大小写。名称的最大长度为64个字符。

    设置用户定义变量的一种方法是发出一条SET语句:

    SET @var_name = expr [, @var_name = expr] ...
    

    对于SET,可以将=:=用作分配运算符。

    可以从一组有限的数据类型中为用户变量分配一个值:整数,十进制,浮点数,二进制或非二进制字符串或NULL值。十进制和实数值的分配不会保留数值的精度或小数位数。除允许类型之一之外的其他类型的值将转换为允许类型。例如,将具有时间或空间数据类型的值转换为二进制字符串。具有JSON数据类型的值将转换为字符集为utf8mb4,排序规则为的字符串utf8mb4_bin

    如果为用户变量分配了非二进制(字符)字符串值,则该变量具有与字符串相同的字符集和排序规则。用户变量的强制性是隐式的。(这与表列值具有相同的强制性。)

    分配给用户变量的十六进制或位值被视为二进制字符串。要将十六进制或位值作为数字分配给用户变量,请在数字上下文中使用它。例如,添加0或使用CAST(... AS UNSIGNED)

    mysql> SET @v1 = X'41';
    mysql> SET @v2 = X'41'	+0;
    mysql> SET @v3 = CAST(X'41' AS UNSIGNED);
    mysql> SELECT @v1, @v2, @v3;
    +------	+------	+------	+
    | @v1  	| @v2  	| @v3  	|
    +------	+------	+------	+
    | A    	|   65 	|   65 	|
    +------	+------	+------	+
    mysql> SET @v1 =  '1000001';
    mysql> SET @v2 =  '1000001'	+0;
    mysql> SET @v3 = CAST( '1000001' AS UNSIGNED);
    mysql> SELECT @v1, @v2, @v3;
    +------	+------	+------	+
    | @v1  	| @v2  	| @v3  	|
    +------	+------	+------	+
    | A    	|   65 	|   65 	|
    +------	+------	+------	+
    

    如果在结果集中选择了用户变量的值,则将其作为字符串返回给客户端。

    如果引用的变量尚未初始化,则其值为NULL和字符串类型。

    用户变量可在允许使用表达式的大多数上下文中使用。这目前不包括明确要求文字值的上下文,如在LIMIT一个条款SELECT声明,或一条款声明。IGNORE N LINESLOAD DATA

    MySQL的早期版本使得可以在以外的语句中为用户变量赋值SET。MySQL 8.0支持此功能以实现向后兼容,但是在将来的MySQL版本中可能会删除该功能。

    以这种方式进行赋值时,必须:=用作赋值运算符。=在之外的语句中被视为比较运算符SET

    涉及用户变量的表达式的求值顺序不确定。例如,不能保证先SELECT @a,@a:=@a +1评估@然后执行分配。

    另外,变量的默认结果类型基于语句开头的类型。如果变量在语句的开头拥有一种类型的值,并且在该语句中还为其分配了另一种类型的新值,则可能会产生意想不到的效果。

    为了避免这种行为的问题,要么不分配一个值和变量一条语句,否则集中读取同一变量的值00.0''在使用前确定其类型。

    HAVING,,GROUP BYORDER BY,当引用在选择表达式列表中分配了值的变量时,不能按预期方式工作,因为该表达式是在客户端上求值的,因此可以使用上一行的陈旧列值。

    用户变量旨在提供数据值。它们不能在SQL语句中直接用作标识符或标识符的一部分,例如在需要表或数据库名称的上下文中,或用作保留字,例如SELECT。即使引用了该变量,也是如此,如以下示例所示:

    mysql> SELECT c1 FROM t;
    +----	+
    | c1 	|
    +----	+
    |  0 	|
    +----	+
    |  1 	|
    +----	+
    2 rows in set (0.00 sec)
    
    mysql> SET @col = "c1";
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT @col FROM t;
    +------	+
    | @col 	|
    +------	+
    | c1   	|
    +------	+
    1 row in set (0.00 sec)
    
    mysql> SELECT `@col` FROM t;
    ERROR 1054 (42S22): Unknown column '@col' in 'field list'
    
    mysql> SET @col = "`c1`";
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT @col FROM t;
    +------	+
    | @col 	|
    +------	+
    | `c1` 	|
    +------	+
    1 row in set (0.00 sec)
    

    用户变量不能用于提供标识符的这一原则的一个例外是,当您构造字符串以用作准备语句以供以后执行时。在这种情况下,用户变量可用于提供语句的任何部分。以下示例说明了如何完成此操作:

    mysql> SET @c = "c1";
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SET @s = CONCAT("SELECT ", @c, " FROM t");
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> PREPARE stmt FROM @s;
    Query OK, 0 rows affected (0.04 sec)
    Statement prepared
    
    mysql> EXECUTE stmt;
    +----	+
    | c1 	|
    +----	+
    |  0 	|
    +----	+
    |  1 	|
    +----	+
    2 rows in set (0.00 sec)
    
    mysql> DEALLOCATE PREPARE stmt;
    Query OK, 0 rows affected (0.00 sec)
    

    可以在应用程序中使用类似的技术来使用程序变量构造SQL语句,如下面使用PHP 5所示:

    <?php
      $mysqli = new mysqli("localhost", "user", "pass", "test");
    
      i ( mysqli_connect_errno() )
        die("Connection failed: %s\n", mysqli_connect_error());
    
      $col = "c1";
    
      $query = "SELECT $col FROM t";
    
      $result = $mysqli->query($query);
    
      while($row = $result->etch_assoc())
      {
        echo "<p>" . $row["$col"] . "</p>\n";
      }
    
      $result->close();
    
      $mysqli->close();
    ?>
    

    以这种方式组装SQL语句有时被称为“动态SQL ”。


    上篇:标识符长度限制

    下篇:表达式