# MySQL怎么自定义变量和语句结束分隔符 ## 一、MySQL变量概述 ### 1.1 变量的定义与作用 在MySQL中,变量是用于存储临时数据的命名存储单元,它们可以在会话或存储过程中保存中间结果、传递参数或控制程序流程。MySQL变量主要分为以下三种类型: 1. **系统变量**:由MySQL服务器维护的预定义变量,控制服务器行为 2. **用户变量**:以`@`开头的会话级变量,仅在当前连接有效 3. **局部变量**:在存储过程/函数中声明的变量,作用域限于程序块 ### 1.2 变量作用域对比 | 变量类型 | 前缀 | 作用域 | 生命周期 | 声明方式 | |---------|------|--------|----------|----------| | 系统变量 | @@ | 全局/会话 | 服务器重启可持久化 | 服务器内置 | | 用户变量 | @ | 会话级 | 当前连接有效 | SET/SELECT | | 局部变量 | 无 | 程序块 | 存储过程执行期间 | DECLARE | ## 二、用户自定义变量详解 ### 2.1 用户变量基本语法 用户变量通过`@变量名`形式表示,无需预先声明: ```sql SET @var_name = expr [, @var_name = expr] ...; -- 或 SELECT @var_name := expr [, @var_name := expr] ...;
示例:
SET @max_salary = (SELECT MAX(salary) FROM employees); SELECT @department_name := '研发部' FROM dual;
SET语句赋值
=
运算符SELECT赋值
:=
赋值运算符MySQL用户变量是动态类型的,其数据类型由赋值的表达式决定:
SET @int_val = 42; -- 整数 SET @float_val = 3.14; -- 浮点数 SET @str_val = 'MySQL'; -- 字符串 SET @date_val = CURDATE(); -- 日期 SET @null_val = NULL; -- NULL值
-- 连接1中设置变量 SET @connection_id = 1; SELECT @connection_id; -- 输出1 -- 新连接中访问同一变量 SELECT @connection_id; -- 输出NULL(不同会话)
局部变量需在存储过程/函数的BEGIN-END块中使用DECLARE声明:
DELIMITER // CREATE PROCEDURE calculate_bonus(IN emp_id INT) BEGIN DECLARE base_salary DECIMAL(10,2); DECLARE bonus_rate FLOAT DEFAULT 0.1; SELECT salary INTO base_salary FROM employees WHERE id = emp_id; SET @bonus := base_salary * bonus_rate; SELECT @bonus AS employee_bonus; END // DELIMITER ;
DELIMITER // CREATE PROCEDURE scope_demo() BEGIN DECLARE x INT DEFAULT 1; -- 外层x BEGIN DECLARE x INT DEFAULT 2; -- 内层x SELECT x; -- 输出2 END; SELECT x; -- 输出1 END // DELIMITER ;
MySQL默认使用分号;
作为语句结束符,这在创建存储过程时会导致问题:
CREATE PROCEDURE test_proc() BEGIN SELECT * FROM table1; -- 会被立即执行 SELECT * FROM table2; END; -- 实际只创建了空过程
临时修改语句分隔符:
DELIMITER new_delimiter -- 后续语句使用new_delimiter作为结束符 DELIMITER ; -- 恢复默认分号
完整示例:
DELIMITER // CREATE TRIGGER before_employee_insert BEFORE INSERT ON employees FOR EACH ROW BEGIN IF NEW.salary < 0 THEN SET NEW.salary = 0; END IF; END// DELIMITER ;
\
(转义字符)//
、$$
等不常见组合SET @table_name = 'employees'; SET @sql = CONCAT('SELECT * FROM ', @table_name, ' LIMIT 10'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @str_num = '123'; SELECT @str_num + 5; -- 隐式转换为数值128 SET @num_str := CONCAT(100, '元'); -- 显式转换为字符串
-- 查看所有系统变量 SHOW VARIABLES; -- 修改会话级变量 SET SESSION sql_mode = 'STRICT_TRANS_TABLES'; -- 修改全局变量(需权限) SET GLOBAL max_connections = 200;
DELIMITER $$ CREATE PROCEDURE paginate_query( IN table_name VARCHAR(100), IN page_size INT, IN page_num INT ) BEGIN DECLARE offset_val INT; SET offset_val = (page_num - 1) * page_size; SET @sql = CONCAT('SELECT * FROM ', table_name, ' LIMIT ', page_size, ' OFFSET ', offset_val); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END$$ DELIMITER ;
DELIMITER // CREATE PROCEDURE backup_table(IN src_table VARCHAR(100), IN backup_suffix VARCHAR(50)) BEGIN DECLARE backup_table_name VARCHAR(150); SET backup_table_name = CONCAT(src_table, '_bak_', backup_suffix); SET @sql = CONCAT('CREATE TABLE ', backup_table_name, ' SELECT * FROM ', src_table); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT CONCAT('Backup created: ', backup_table_name) AS result; END// DELIMITER ;
-- 错误示范 SELECT @undefined_var + 1; -- 结果为NULL -- 正确做法 SET @undefined_var = IFNULL(@undefined_var, 0); SELECT @undefined_var + 1;
当SQL中包含分号时(如创建触发器):
DELIMITER $$ CREATE TRIGGER update_timestamp BEFORE UPDATE ON orders FOR EACH ROW BEGIN SET NEW.update_time = NOW(); -- 这里的分号不会终止语句 END$$ DELIMITER ;
DELIMITER // CREATE PROCEDURE variable_scope_demo() BEGIN DECLARE local_var INT DEFAULT 10; SET @user_var = 20; SELECT local_var, @user_var; -- 正确 END// DELIMITER ; -- 外部无法访问local_var CALL variable_scope_demo(); SELECT @user_var; -- 可访问 SELECT local_var; -- 错误!
@customer_count
)通过掌握MySQL变量和分隔符的使用技巧,可以显著提高数据库操作的灵活性和效率。建议在实际开发中结合具体业务场景,合理运用这些特性来优化数据库交互。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。