如何在MySQL中声明变量?

How to declare a variable in MySQL?

提问人:cdub 提问时间:8/1/2012 最后编辑:Andrew Junzkicdub 更新时间:8/2/2023 访问量:1055408

问:

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

我想写这样的东西:

SET start = 1;
SET finish = 10;

SELECT * FROM places WHERE place BETWEEN start AND finish;
MySQL 数据库

评论

1赞 Steve Smith 11/7/2019
不要忘记您可能需要“允许用户变量=True”。

答:

909赞 Omesh 8/1/2012 #1

MySQL中主要有三种类型的变量:

  1. 用户定义的变量(以 @ 为前缀):

    您可以访问任何用户定义的变量,而无需声明它或 初始化它。如果您引用的变量尚未 initialized,它的值为 和 字符串类型。NULL

    SELECT @var_any_var_name
    

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

    SET @start = 1, @finish = 10;    
    

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

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

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

    它们可以在使用高级MySQL用户变量技术的查询中使用。SELECT

  2. 局部变量(无前缀):

    局部变量需要声明 before 访问它。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);
    

    如果缺少该子句,则初始值为 。DEFAULTNULL

    局部变量的作用域是 它被宣布。BEGIN ... END

  3. 服务器系统变量(以 @@ 为前缀):

    MySQL服务器维护许多配置为默认值的系统变量。 它们可以是 类型 ,也可以是 。GLOBALSESSIONBOTH

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

    若要查看正在运行的服务器使用的当前值,请使用语句 或 。SHOW VARIABLESSELECT @@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;
    

评论

3赞 divinedragon 2/25/2014
不知何故,操作员对我不起作用。当我使用运算符时,它工作正常。=:=
43赞 Omesh 2/26/2014
=运算符仅在子句中起作用。为了在查询中为变量赋值,您可以使用运算符,例如SETSELECT:=SELECT @start := 1
3赞 But those new buttons though.. 4/24/2015
您能否澄清一下这是什么意思:“无需声明用前缀 @ 表示的用户定义会话变量”?
4赞 jobo3208 6/22/2015
@billynoah 我假设这意味着用户定义的会话变量(以 @ 开头)不需要显式声明;您可以立即分配给它们,就好像它们已经声明一样。
3赞 Software Prophets 9/6/2016
你可以用这样的选择语句的结果分配一个变量:SET @subscriptionId = (select subscriptionId from User where emailAddress='[email protected]');
26赞 Mohammad Mahdi KouchakYazdi 12/24/2016 #2

使用设置选择

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

例:

SELECT @price := MAX(product.price)
FROM product 
72赞 bortunac 1/19/2017 #3

设置

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

接受运算符 = 和 :=


选择

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

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

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

在这种情况下,结果不包含值Selectcol2


例如,使用的两种方法

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

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

评论

3赞 Koray Tugay 11/30/2017
和 和有什么不一样?=:=
2赞 bortunac 11/30/2017
我想对于mysql,SELECT语法对于将=(比较)与:=(asign)的含义分开是必要的
2赞 Doin 7/8/2019
在某些情况下,变量中保留的值可能与返回的最后一行不对应。例如,似乎在完成排序之前评估变量赋值,因此返回的 @var 值甚至可能与任何返回的行无关。不过,文档没有说明在什么条件下会发生这种情况。SELECT DISTINCT IFNULL(@var:=Name,'unknown') FROM Customers ORDER BY <some non-indexed expression> LIMIT 10
4赞 Imran Javed 11/28/2018 #4

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

Set @Ids = '';

select 
  @Ids := concat_ws(',',@Ids,tbl.Id),
  tbl.Col1,
  ...
from mytable tbl;
-2赞 Hari Lakkakula 5/30/2019 #5

SET 值

 declare @Regione int;   
 set @Regione=(select  id from users
 where id=1) ;
 select @Regione ;
17赞 mohammadAli 8/6/2019 #6

不同类型的变量:

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

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

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

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

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

设置 @countTotal = (SELECT COUNT(*) FROM nGrams);

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

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

11赞 yaya 11/9/2019 #7
  • 宣:SET @a = 1;

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

评论

1赞 carloswm85 12/8/2021
t对于表和列?c
1赞 yaya 1/30/2022
@carloswm85是的
0赞 Jean Carlos Souza 9/28/2022 #8

我想在这里提供我的awnswer,以便人们可以尝试我认为更容易理解的MySql解决方案:

set @countVal =  (select count(*) from STATION);
/**
499/2 = 249,5 -> 250 -- ceil
499/2 = 249,5 + 1 = 250,5 -- floor 250

500/2 = 250 -- ceil 250
       = 250 + 1 = 251 -- flor 251
**/       
set @ceilVal = ceil(@countVal/2);
set @floorVal = floor( (@countVal/2) + 1);
SELECT ROUND(AVG( latitude ),4) FROM
(SELECT @lineNum:= @lineNum + 1 as id, 
lat_n as latitude
FROM STATION s, ( SELECT @lineNum :=0 ) pivot
ORDER BY lat_n) as a
WHERE id IN ( @ceilVal, @floorVal );
0赞 Oscar Adolfo Méndez Muñoz 8/2/2023 #9

在变量声明之间使用分号,这是一个使用 phpMyAdmin 对我有用的示例。这样,我们必须为运行的每个查询声明变量。

[![Using Variables with mySql][1]][1]

SET @solicitud = 1;
SET @despacho = 1;
SET @recibe = 2;
SET @entrega = 123;
SET @firma = 'ABCD';
SET @equipo = 1124;
SET @sim = 123;
SET @fecha = '2023-07-07 13:43:20';

INSERT INTO `avl_equipo_tecnico` (`eqt_solicitud`, `eqt_equipo`, `eqt_usuario`, `eqt_despacho`, `eqt_fecha_registro`, `eqt_usuario_registro`, `eqt_situacion`) VALUES (
@solicitud,     -- solicitud 
@equipo,    -- equipo = ane_equipo 
@recibe,    -- usuario que recibe
@despacho,  -- despacho = ane_despacho
@fecha,     -- = ane_fecha_registro
@entrega,   -- el mismo que el anterior
'1'     -- situacion =1
);