如何在shell脚本使用 MySQL 命令行给 SQL 文件传参

在编写 Shell 脚本或进行命令行操作时,有时需要执行包含预定义 SQL 语句的文件,并且可能希望根据不同的情况向这些 SQL 文件传递参数。这在批量处理、自动化任务或动态生成查询时特别有用。MySQL 的命令行工具提供了执行 SQL 文件的能力,但直接从命令行传递参数到 SQL 文件的功能有限。因此,我们通常会结合使用文本处理工具如 sed 来实现这一点。

使用 sed 预处理 SQL 文件

sed 是一个流编辑器,可以在不打开文件的情况下对文件内容进行各种操作,比如替换文本、插入文本等。我们可以利用 sed 在执行 SQL 文件之前修改其中的占位符,将实际的参数值写入 SQL 文件中。下面是一个简单的例子:

假设有一个名为 insertstmt.sql 的 SQL 文件,其内容如下:

INSERT INTO test.demo_table VALUES(@name, @age);

这里 @name@age 是我们需要从外部传递的参数。为了实现这一点,我们可以创建一个 Shell 脚本 execute.sh,它接受两个参数并用它们来替换 yoursql.sql 中的变量:

#!/bin/sh
# 设置参数作为 SQL 变量并添加到 yoursql.sql 文件的第一行
sed -i "1 i\ SET @name='$1';" yoursql.sql
sed -i "1 i\ SET @age=$2;" yoursql.sql

# 执行 SQL 脚本
mysql -u root < yoursql.sql

# 清除 SQL 脚本中的变量设置
sed -i '1,2d' yoursql.sql

在这个脚本中,$1$2 分别对应于调用脚本时提供的第一个和第二个参数。当我们运行这个脚本,例如 ./execute.sh lenmom 30,它会先修改 yoursql.sql 文件,使其看起来像这样:

SET @name='lenmom';
SET @age=30;
INSERT INTO test.demo_table VALUES(@name, @age);

然后执行该 SQL 文件,最后恢复原始状态以供下次使用。

安全性与最佳实践

虽然上述方法可以很好地工作,但在实际应用中需要注意几个方面:

  • 安全性:当构建 SQL 查询字符串时,确保对外部输入进行了适当的转义,以防止 SQL 注入攻击。
  • 错误处理:考虑加入错误处理逻辑,以便在出现问题时能够及时通知用户。
  • 日志记录:记录每次操作的日志对于追踪问题和审计非常重要。
  • 备份机制:如果直接修改了 SQL 文件,在执行前最好先创建一个副本以防万一。

实际案例分析

让我们来看一个更复杂的实例,其中涉及到数据库连接信息以及多个参数的传递。想象一下,你有一个定期更新用户信息的任务,需要每天晚上更新一次特定用户的年龄信息。你可以创建一个名为 update_user_age.sh 的 Shell 脚本来完成这项任务:

#!/bin/bash
# 数据库连接信息
DB_HOST="localhost"
DB_PORT="3306"
DB_USER="root"
DB_PASS="password"

# 用户名和新年龄作为参数传递
USER_NAME="$1"
NEW_AGE="$2"

# 更新 SQL 文件中的变量
sed -i "1 i\ USE my_database;" update_user_age.sql
sed -i "2 i\ UPDATE users SET age = $NEW_AGE WHERE username = '$USER_NAME';" update_user_age.sql

# 执行更新
mysql -h "$DB_HOST" -P "$DB_PORT" -u "$DB_USER" -p"$DB_PASS" < update_user_age.sql

# 恢复 SQL 文件
sed -i '1,2d' update_user_age.sql

此脚本首先指定了数据库连接的信息,接着接收用户名和新的年龄作为参数,并使用 sed 将这些参数插入到 update_user_age.sql 文件中。之后通过 MySQL 命令执行更新操作,最后清理临时添加的内容,保证 SQL 文件的干净。

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。更多免费资源在http://www.gitweixin.com/?p=2627

发表评论

邮箱地址不会被公开。 必填项已用*标注