安装软件时,初始化数据库往往需要执行多个 .sql 文件,而且必须按编号顺序来。手工一个个执行既慢又容易漏,笔者这里分享一个封装思路:先生成一个总控脚本,再交给数据库一次性跑完。
01 | 先看清目录里的文件
初始化目录里通常有多个 .sql,文件名带数字前缀,例如:
bash
$ ls -lrth
total 92K
-rw-r--r-- 1 oracle oinstall 2.1K Oct 15 17:35 999-security-context.md
-rw-r--r-- 1 oracle oinstall 825 Oct 15 17:35 400-rdf-network.sql
-rw-r--r-- 1 oracle oinstall 8.9K Oct 15 17:35 310-rdf-ontology.sql
-rw-r--r-- 1 oracle oinstall 46K Oct 15 17:35 300-data.sql
-rw-r--r-- 1 oracle oinstall 3.3K Oct 15 17:35 200-changes.sql
-rw-r--r-- 1 oracle oinstall 13K Oct 15 17:35 100-dbobjects.sql
数字前缀就是执行顺序的依据,从 100 到 400 依次执行即可。
02 | 生成总控脚本
核心做法是用循环把每个 .sql 拼进一个 run_all.sql,并加上错误退出、回显和计时等设置:
bash
{
echo "-- ========================================"
echo "-- Auto-generated Oracle Deployment Script"
echo "-- ========================================"
echo "WHENEVER SQLERROR EXIT SQL.CODE;"
echo "SET ECHO ON;"
echo "SET TIMING ON;"
echo ""
# 获取所有 sql,按版本号排序,并排除 run_all.sql 自身
for f in $(printf '%s\n' *.sql | sort -V | grep -v '^run_all\.sql$'); do
echo "PROMPT Executing: $f"
echo "@@$f"
echo ""
done
echo "PROMPT === All scripts executed successfully ==="
echo "COMMIT;"
} > run_all.sql
生成后,进入这些 .sql 文件所在目录(@@ 是相对当前工作目录解析的),用具备相应权限的数据库用户连接,再执行 run_all.sql。脚本设置了 WHENEVER SQLERROR EXIT SQL.CODE,任一语句报错会立即退出,此时需先排查并修复失败脚本,再重新执行;建议在测试环境验证后再用于生产。
03 | 为什么这样可行
关键在两点:
sort -V按版本号排序,100、200、300这样的数字前缀能自然排对,不会出现字符串排序的错位。grep -v '^run_all\.sql$'精确剔除run_all.sql自身。因为生成的目标文件也在同一目录,如果不排除,重复生成时它会被再次写进列表,造成自我引用。
这样无论运行多少次生成命令,控制脚本里都只包含业务 .sql 文件,不会自我引用。不过它并不保证脚本可重复执行:若初始化 SQL 不是幂等的,重复运行可能造成数据重复或报错,生产环境执行前应先备份并确认脚本的幂等性。
关注我,和AI一起成长~