MySQL 命令行执行SQL的细节
MySQL 命令行执行SQL的细节
背景
经过调试与验证,我们可以确信自己编写的SQL是正确的,是时候到目标库执行SQL了!
但要小心,在正式环境中执行 SQL,也许会有意想不到的坑!
环境说明
先说明下我们的环境信息。
我们只能通过跳板机的终端连接 mysql、执行SQL,没有DBeaver、Navicat等工具可用。
则我们执行SQL语句的方式有两种:
- 执行导出的SQL语句文件
- 复制粘贴SQL语句执行
当然,在执行前,我们要确保已进行了数据备份。
执行SQL文件
执行SQL文件是最简单的,一般实践也是在命令行批量执行SQL文件。
相关的命令与恢复备份的命令一致:
mysql -h your-ip -u your-username -p${password} your-database < script.sql
这是推荐的方式,因为执行语句一旦出错,就会停下,并告知是第几行的语句出错。
但出于某些原因,你可能不想把所有SQL语句都合并到一个 script.sql 文件中。
另外,上传文件到跳板机,可能也比较麻烦,于是,你想采用第二种方式。
复制粘贴执行
通过 mysql 客户端直接上 MySQL 后,在命令上执行 SQL 语句会有一个问题:错误的语句不会中断后续的执行。
更可怕的是在命令行里,很可能你SQL语句包括的中文字符串会被过滤掉,变成空字符串。如:
- '创建人' -> ''
- '中英en混杂' -> 'en'
这真是血的教训😭。
我们先来看下错误是否中断的实验。
新建一个只有两行的SQL文件,其中第一行语句是错误的。
ss;
select 1;
使用导入命令:
mysql -h your-ip -u your-username -p${password} your-database < test.sql
提示第一行有错误,第二行未执行。这是符合期望的。
但如果连接 mysql 后,在交互式命令行里执行 source 命令:
错误出现并不会中断SQL的执行。
复制语句,粘贴到命令行,表现也是如此:错误只提示,不中断执行。
那么,能否在交互式命令行里执行SQL语句,一旦错误就中断呢?
我们在MySQL官方论坛里找到了相关的帖子:
最终得到的答案是,使用:\e。
进行类vi界面,在这里粘贴 SQL(这里就不会有中文被过滤的问题)
保存退出后,输入 ;
则执行 SQL 语句,Ctrl + C 则不执行。
可以看到,这种方式执行 SQL 语句,也是可以遇到错误就中断的。
如果要删除错误的数据怎么办?
尽管经过测试,但也不敢说语句的执行能百分之分成功,因此,这里给个温馨提醒。
如果插入、更新了错误的数据,确实要执行 DELETE 语句,那么请做好以下 checklist:
- 确保已备份数据
- 删除前先查询,也即先写 select from,确认一下是目标数据,再改写成 select 改写成 delete
- 一定要写 where 语句,并且精确到主键,最好只写类似这种语句 where id = 1 或者 where id in (1,2)