nodejs操作mysql与sqlite数据库

const query = (sql, values) => {
    return new Promise((resolve, reject) => {
        if (isMySQL) {
            pool.getConnection((err, connection) => {
                if (err) {
                    writeFileLog(err);
                    reject(err);
                    return;
                }

                connection.query(sql, values, (err, results) => {
                    connection.release();

                    if (err) {
                        console.log(err);
                        writeFileLog(err);
                        reject(err);
                    } else {
                        resolve(results);
                    }
                });
            });
        } else {
            const trimmedSql = sql.trim(); // 去除开头和结尾的空格
            if (trimmedSql.toLowerCase().startsWith('select')) { // 处理 select 查询
                connection.all(trimmedSql, values, (err, rows) => {
                    if (err) {
                        writeFileLog(err);
                        reject(err);
                    } else {
                        resolve(rows);
                    }
                });
            } else {
                // 检查是否是批量插入
                if (trimmedSql.toLowerCase().startsWith('insert') && Array.isArray(values) && Array.isArray(values[0])) {
                    // 将二维数组转换为字符串形式的占位符和值
                    // const placeholders = values.map(
                    //     () => `(${new Array(values[0][0].length).fill('?').join(', ')})`
                    // ).join(', ');
                    // const flattenedValues = values.flat();

                    // // 替换 SQL 语句中的占位符
                    // const batchSql = trimmedSql.replace('?', placeholders);

                    // let promises = flattenedValues.map(value => {
                    //     return new Promise((resolve, reject) => {
                    //         connection.run(batchSql, value, function (err) {
                    //             if (err) {
                    //                 writeFileLog(err);
                    //                 reject(err);
                    //             } else {
                    //                 resolve(this.changes); // 返回受影响的行数
                    //             }
                    //         });
                    //     });
                    // });

                    // Promise.all(promises)
                    //     .then(results => resolve(results))
                    //     .catch(err => reject(err));
                    
                    //上面注释的是逐条插入,效率慢,改成构建insert into table (id,name) values (?,?),(?,?)...这样的sql进行批量插入
                    // const dataArray = values[0]; // `values` 是二维数组,取第一维度
                    // const numFields = dataArray[0].length;
                    // const placeholders = new Array(dataArray.length).fill(`(${new Array(numFields).fill('?').join(', ')})`).join(', ');

                    // // 生成完整的 SQL 语句
                    // const batchSql = trimmedSql.replace('?', placeholders);

                    // // 展平值数组
                    // const flattenedValues = dataArray.flat();

                    // connection.run(batchSql, flattenedValues, function (err) {
                    //     if (err) {
                    //         writeFileLog(err);
                    //         reject(err);
                    //     } else {
                    //         resolve(this.changes); // 返回受影响的行数
                    //     }
                    // });
                    //避免SQLITE_ERROR: too many SQL variables,进行批量插入
                    const dataArray = values[0]; // `values` 是二维数组,取第一维度
                    const numFields = dataArray[0].length;
                    const batchSize = 2000; // 每次批量插入的记录数
                    let currentBatchStart = 0;
                    const totalRecords = dataArray.length;

                    function insertBatch() {
                        if (currentBatchStart >= totalRecords) {
                            resolve(); // 插入完成,返回
                            return;
                        }

                        // 获取当前批次的数据
                        const currentBatch = dataArray.slice(currentBatchStart, currentBatchStart + batchSize);
                        const placeholders = new Array(currentBatch.length).fill(`(${new Array(numFields).fill('?').join(', ')})`).join(', ');

                        // 构建批量插入的 SQL 语句
                        const batchSql = trimmedSql.replace('?', placeholders);

                        // 展平当前批次的值
                        const flattenedValues = currentBatch.flat();

                        // 执行批量插入
                        connection.run(batchSql, flattenedValues, function (err) {
                            if (err) {
                                writeFileLog(err);
                                reject(err);
                            } else {
                                currentBatchStart += batchSize;
                                insertBatch(); // 插入下一个批次
                            }
                        });
                    }

                    // 开始分批插入
                    insertBatch();
                } else {
                    connection.run(trimmedSql, values, function(err) {
                        if (err) {
                            writeFileLog(err);
                            reject(err);
                        } else {
                            resolve(this.changes); // 返回受影响的行数
                        }
                    });
                }
            }
        }
    });
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌晨两点钟同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值