在Bash Here-Document中编写MariaDB存储过程触发1064语法错误
在Bash Here-Document中编写MySQL存储过程的语法错误解决
问题场景
通过Bash脚本的Here-Document编写MySQL存储过程,已用单引号包裹EOF避免Bash变量展开,但在存储过程的BEGIN/END块中添加SQL语句时,触发如下语法错误:
ERROR 1064 (42000) at line 6: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 4
原脚本代码:
#!/bin/bash function cp() { mysql --verbose --line-numbers -uxxx -pxxx << 'EOF' use mysql; SELECT COUNT(*) FROM mysql.user; drop PROCEDURE if exists test; create PROCEDURE `test` () BEGIN -- SELECT COUNT(*) FROM mysql.user END; EOF }
执行脚本后的输出片段:
xxx:~# . querylog.sh cp -------------- SELECT COUNT(*) FROM mysql.user -------------- COUNT(*) 13 -------------- drop PROCEDURE if exists test -------------- -------------- create PROCEDURE `test` () BEGIN END --------------
解决方法
问题根源是MySQL默认的语句分隔符;会中断存储过程的定义解析。当BEGIN/END块内存在带分号的语句时,MySQL会误将其当成整个存储过程的结束,导致语法错误。需要自定义分隔符来规避这个问题:
修改后的完整脚本:
#!/bin/bash function cp() { mysql --verbose --line-numbers -uxxx -pxxx << 'EOF' use mysql; SELECT COUNT(*) FROM mysql.user; DELIMITER // drop PROCEDURE if exists test// create PROCEDURE `test` () BEGIN SELECT COUNT(*) FROM mysql.user; END// DELIMITER ; EOF }
关键修改点
- 添加
DELIMITER //:将MySQL的语句分隔符临时改为//,避免分号干扰存储过程定义 - 存储过程相关语句(
drop PROCEDURE、create PROCEDURE的END)末尾用//代替; - 最后通过
DELIMITER ;恢复默认分隔符
这样MySQL就能正确识别整个BEGIN/END块为存储过程的内容,不会提前解析终止,从而避免语法错误。
内容的提问来源于stack exchange,提问作者stesans
相关产品推荐
相关产品推荐

