sql中变量如何声明和使用 局部变量和全局变量的声明赋值指南

那天我在调试一个存储过程,发现SQL Server的局部变量@TotalCount居然被嵌套查询覆盖了,结果计数对不上。
赶紧加了个@OuterTotalCount,问题解决。
想想也是,局部变量就像办公室抽屉里的笔,你用完它就不见了,外面谁也别想碰。
但MySQL的DECLARE语句不用@前缀,确实省事。
我有个朋友用MySQL写函数,总把DECLARE和BEGIN写混,最后发现是IDE提示颜色太像。
SQL Server的@@IDENTITY比MySQL的LAST_INSERT_ID()更方便啊,但MySQL的GROUP_CONCAT()函数简直神了,SQL Server还得自己写临时表。
不过说到底,变量名命名还是得正经点,上次我看某同事的存储过程,变量叫@temp,嵌套三层后还在用,最后调试花了俩小时。
全局变量这东西,感觉就像公司大喇叭喊通知,方便是真方便,但你要是忘了关,全楼层都听见。

浅谈MySQL存储过程中declare和set定义变量的区别

说白了,MySQL存储过程中定义变量有两种方式,其实很简单。
先说最重要的,第一种是使用set或select直接赋值,变量名以@开头,比如:set@var=1 ;。
这种方式定义的变量是会话变量,作用域是整个会话,可以反复使用,就相当于会话内的全局变量。
另外一点,第二种是以DECLARE关键字声明的变量,只能在存储过程中使用,比如:DECLARE var1 INT DEFAULT 0;。
这种变量是存储过程变量,主要用在存储过程中,或者是给存储传参数中。

我一开始也以为两种变量都可以在会话中随意使用,后来发现不对,DECLARE声明的变量在调用存储过程时都会被初始化为NULL,而会话变量则不会。
还有个细节挺关键的,就是当你使用动态语句时,预处理时,动态内容必须赋给一个会话变量。

所以,如果你想在存储过程中使用变量,记得根据需要选择合适的变量类型。
这个点很多人没注意,但我觉得值得试试。
等等,还有个事,如果你在存储过程中使用动态SQL,记得先设置会话变量,然后再进行预处理和执行。
说实话挺坑的,但掌握了门道之后,使用起来就顺畅多了。

mysql中declare的用法

哎哟喂,跟你说个事儿,我当年刚接触MySQL那会儿, DECLARE 这玩意儿真是把我绕得团团转。
你说的这些,我基本都踩过坑。

比如那年,我在上海搞一个电商项目,写个存储过程统计销售额。
一开始我这么写: sql DECLARE total_sales DECIMAL(1 0,2 ); SELECT SUM(amount) INTO total_sales FROM orders WHERE status='completed';
结果呢?报错,说 total_sales 没有初始化。
我愣了半天,才发现 DECLARE 声明必须在存储过程的最开始,不能跟别的语句混着来。
这下好,重写一遍,把 DECLARE 放在最前面,才搞定。

再说说游标,那年我在深圳做用户数据迁移,得按部门逐个处理员工信息。
我写了个存储过程,结果这么写: sql DECLARE emp_cursor CURSOR FOR SELECT id, name FROM employees WHERE department='IT'; OPEN emp_cursor; FETCH emp_cursor INTO emp_id, emp_name;
运行?直接崩。
后来我才搞明白,DECLARE 只是定义游标,还得 OPEN,还得 FETCH,还得 CLOSE。
我那个存储过程最后长这样: sql DECLARE emp_cursor CURSOR FOR SELECT id, name FROM employees WHERE department='IT'; DECLARE emp_id INT; DECLARE emp_name VARCHAR(1 00); DECLARE done INT DEFAULT FALSE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN emp_cursor; read_loop: LOOP FETCH emp_cursor INTO emp_id, emp_name; IF done THEN LEAVE read_loop; END IF; -
这里插入处理逻辑,比如 INSERT INTO temp_table (id, name) VALUES (emp_id, emp_name); END LOOP; CLOSE emp_cursor;
才对。
你看,DECLARE 只是开始,后面一堆操作不能少。

最让我头疼的是作用域。
那年我在杭州搞一个报表系统,写个存储过程,结果变量作用域搞错了,外面也访问得到,数据全乱套。
后来才改明白,DECLARE 的变量只能在当前 BEGIN...END 块里用,不能跨块。
这下好,把所有 DECLARE 都移到最前面,才没出事。

总结一下,DECLARE 这玩意儿啊,用好了省事,用不好坑死人。
记住三点:1 . 必须在存储过程、函数或触发器里用;2 . 声明必须在最前面,不能混其他语句;3 . 变量和游标都得完整操作,不能只声明不执行。
我当年就是踩着这三点坑过来的。

哦对了,你问游标怎么用?我举个例子。
去年我在成都搞一个订单处理系统,得按批次逐行更新订单状态。
我这么写的: sql DECLARE order_cursor CURSOR FOR SELECT order_id FROM orders WHERE status='pending' LIMIT 1 000; DECLARE done INT DEFAULT FALSE; DECLARE current_order_id INT;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN order_cursor; process_loop: LOOP FETCH order_cursor INTO current_order_id; IF done THEN LEAVE process_loop; END IF; -
更新订单状态 UPDATE orders SET status='processing' WHERE order_id=current_order_id; END LOOP; CLOSE order_cursor;
你看,DECLARE 定义游标,FETCH 逐行取,UPDATE 逐行处理。
这样批量处理才不会卡死数据库。

还有啊, DECLARE 不能在普通 SQL 语句里用。
你非要用,比如在 SELECT 语句里 DECLARE 个变量,直接报错。
当年我有个同事就犯这个错,写了个 SQL 查询想声明个计数器,结果整得数据库崩了半天。

总的来说,DECLARE 用得对,临时变量和游标都方便。
用得不对,存储过程写一半就崩。
我给你总结个场景,你看看有没有用:
声明变量:存储中间结果,比如计算总金额、计数器。

声明游标:逐行处理数据,比如部门遍历、订单逐条更新。

注意:必须在存储程序里,声明在开头,完整操作。

你看,我说的都是亲身经历。
你要是还有问题,我再跟你细聊。