如何在Bash脚本中执行含自定义变量的多SQL查询并通过.cnf连接数据库?
在Bash脚本中执行带变量的多SQL删除查询
完全可以实现你想要的需求——用用户输入的SUBJECT_ID变量批量执行删除查询,而且不推荐直接在命令行明文写密码,用.cnf配置文件管理数据库连接更安全。以下是具体实现方案:
一、先准备安全的数据库连接配置
创建一个MySQL客户端配置文件(比如~/.mysql_auth.cnf),用来存储连接信息,避免密码暴露在脚本或命令行中:
[client] host = server-name user = root password = 你的数据库密码 database = 目标数据库名
然后给这个文件设置严格权限,防止其他用户读取:
chmod 600 ~/.mysql_auth.cnf
二、两种脚本实现方式
方式1:脚本内直接嵌入所有删除SQL(适合少量查询)
这种方式不用额外的SQL文件,直接在Bash脚本里写所有删除语句:
#!/bin/bash # 读取用户输入的Subject ID read -p 'Subject ID: ' SUBJECT_ID # 校验输入不为空 if [ -z "$SUBJECT_ID" ]; then echo "错误:Subject ID不能为空" exit 1 fi # 转义变量,防止SQL注入(如果ID可能包含单引号等特殊字符) ESCAPED_ID=$(mysql --defaults-extra-file=~/.mysql_auth.cnf --skip-column-names -e "SELECT QUOTE('$SUBJECT_ID')") # 执行批量删除查询 mysql --defaults-extra-file=~/.mysql_auth.cnf << EOF # 注意顺序:先删关联子表,再删主表,避免外键约束报错 DELETE FROM 子表1 WHERE subject_id = $ESCAPED_ID; DELETE FROM 子表2 WHERE subject_id = $ESCAPED_ID; DELETE FROM 主表 WHERE subject_id = $ESCAPED_ID; # 继续添加其他需要执行的删除语句 EOF # 检查执行结果 if [ $? -eq 0 ]; then echo "所有删除操作执行成功" else echo "删除操作执行失败,请检查日志" exit 1 fi
方式2:调用外部SQL文件(适合大量查询)
如果删除语句很多,可以把SQL单独存成文件(比如delete_subject_data.sql):
DELETE FROM 子表1 WHERE subject_id = ?; DELETE FROM 子表2 WHERE subject_id = ?; DELETE FROM 主表 WHERE subject_id = ?;
然后在Bash脚本中传入变量执行:
#!/bin/bash read -p 'Subject ID: ' SUBJECT_ID if [ -z "$SUBJECT_ID" ]; then echo "错误:Subject ID不能为空" exit 1 fi # 方式A:用MySQL 8.0.19+支持的绑定变量(最安全) mysql --defaults-extra-file=~/.mysql_auth.cnf --execute="source delete_subject_data.sql" --bind-vars=subject_id="$SUBJECT_ID" # 方式B:旧版MySQL可用sed替换占位符后执行 # sed "s/?/$SUBJECT_ID/g" delete_subject_data.sql | mysql --defaults-extra-file=~/.mysql_auth.cnf # 检查执行结果 if [ $? -eq 0 ]; then echo "删除操作执行成功" else echo "删除操作失败" exit 1 fi
三、关键注意事项
- 删除顺序:因为没开cascade,必须先删除依赖主表的子表数据,再删主表数据,否则会触发外键约束报错。
- SQL注入防护:如果
SUBJECT_ID可能包含单引号、反斜杠等特殊字符,一定要用QUOTE()函数转义,或者用绑定变量的方式,避免注入风险。 - 权限问题:确保运行脚本的用户能读取
.cnf配置文件,且数据库账号有对应表的删除权限。
内容的提问来源于stack exchange,提问作者Michał Różga
相关产品推荐
相关产品推荐

