NodeJs里面mysql2执行sql文件
一、背景
Electron项目导入sql压缩包并解压,执行里面每一个sql脚本,使用的是mysql2
二、步骤
- 导入mysql2 并创建了 连接换成池子
import mysql from 'mysql2';
// 创建数据库连接池
const pool = mysql.createPool({
host: dbConfig.host,
user: dbConfig.user,
password: dbConfig.password,
database: dbConfig.database,
port: dbConfig.port || 3306, // 如果没有提供 port,则使用默认端口 3306
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
- 获取连接执行sql
const connection = await pool.promise().getConnection();
try {
// 开启事务
connection.beginTransaction();
// 逐个执行 SQL 文件
for (const file of sqlFiles) {
const sqlContent = fs.readFileSync(file, 'utf8')// 去除 /**/ 这种块级注释
.replace(/--.*$/gm, '') // 移除单行注释
.replace(/\/\*[\s\S]*?\*\//g, ''); // 移除多行注释
console.log(`执行 SQL 文件: ${file}`);
const sqlStatements = sqlContent
.split(/(;)(?=(?:(?:[^'"]|'[^']*'|"[^"]*")*?)$)/g) // 拆分 SQL 语句但排除字符串内部的分号
.filter((stmt, index, arr) => {
// 保证分割出来的元素是有效 SQL 语句,并且不是空字符串或仅包含分号
return stmt.trim() !== '' && stmt.trim() !== ';';
})
.map(stmt => stmt.trim()); // 去除每条 SQL 语句两端的空白字符
for(let sql of sqlStatements){
// 执行文件中的 SQL 语句
await connection.execute(sql).then((results)=>{
//console.log(results);
sendLog(sql);
});
}
}
// 如果所有文件执行成功,提交事务
connection.commit();
console.log('所有 SQL 文件执行成功!');
sendLog('所有 SQL 文件执行成功!');
await connection.query('SELECT db_version FROM szhmc_db_version').then(([result]) => {
let version = result.length > 0 ? result[0].db_version : '';
sendLog('升级到版本:' + version);
});
} catch (error) {
// 如果发生错误,回滚事务
connection.rollback();
console.error('执行 SQL 文件时发生错误,已回滚事务:', error);
sendLog('执行 SQL 文件时发生错误,已回滚事务:' + error);
} finally {
// 释放连接
connection.release();
}
这里有2个坑,一个是sql文件里面存在注释要去除,第二个要把sql文件里面的每一个sql单独提取出来一个一个执行。