Nodejs批量更新数据问题,请大神指教

Nodejs批量更新数据问题,请大神指教

我在做一个项目时遇到需要使用Nodejs去跟新数据,使用的数据库是Postgres,但问题是同样的sql语句,我使用Postgres直接跑sql是可以完全更新的,但是使用Nodejs去跑数据,总有零星几个字段是空的。请教大神这会是什么原因?

sql语句是这样的,因为架构的需要循环了大概540次。 UPDATE eagleeye_kpi_company SET previous_1=( SELECT CAST(index_value AS FLOAT)
FROM etms_kpi_index_company_value
WHERE index_id='AvgDailyCallClientCount’ AND month=‘201403’
AND index_value!=’-'
AND tenant_id='nestle-uat’
AND eagleeye_kpi_company.company_id=etms_kpi_index_company_value.company_id)
WHERE eagleeye_kpi_company.kpi_id='KPI_06’
AND eagleeye_kpi_company.tenant_id=‘nestle-uat’


6 回复

当然可以!让我们来分析一下这个问题,并提供一些可能的解决方案。

问题分析

你提到在使用 Node.js 更新数据时,虽然相同的 SQL 语句在 PostgreSQL 中可以直接运行成功,但在 Node.js 中执行时却总有个别字段为空。这种情况通常与以下几个方面有关:

  1. 事务管理:确保所有操作在一个事务中进行,以保证数据的一致性。
  2. 错误处理:检查是否有任何错误或异常被忽略。
  3. 并发问题:如果有多线程或多进程同时更新同一行数据,可能会导致数据不一致。

示例代码

我们可以通过以下步骤来解决这个问题:

  1. 使用事务:确保所有更新操作在一个事务中进行。
  2. 错误处理:添加适当的错误处理逻辑。
  3. 日志记录:添加日志记录,以便跟踪问题。
const { Client } = require('pg');

async function updateData() {
    const client = new Client({
        user: 'your_user',
        host: 'your_host',
        database: 'your_database',
        password: 'your_password',
        port: 5432,
    });

    await client.connect();

    try {
        // 开始一个事务
        await client.query('BEGIN');

        for (let i = 1; i <= 540; i++) {
            const sql = `
                UPDATE eagleeye_kpi_company 
                SET previous_1=(
                    SELECT CAST(index_value AS FLOAT)
                    FROM etms_kpi_index_company_value
                    WHERE index_id='AvgDailyCallClientCount'
                    AND month='201403'
                    AND index_value != '-'
                    AND tenant_id='nestle-uat'
                    AND eagleeye_kpi_company.company_id=etms_kpi_index_company_value.company_id
                )
                WHERE eagleeye_kpi_company.kpi_id='KPI_06'
                AND eagleeye_kpi_company.tenant_id='nestle-uat';
            `;

            const result = await client.query(sql);

            // 检查是否有错误
            if (result.rowCount === 0) {
                console.log(`No rows updated for iteration ${i}`);
            }
        }

        // 提交事务
        await client.query('COMMIT');
    } catch (err) {
        // 回滚事务
        await client.query('ROLLBACK');
        console.error('Error updating data:', err);
    } finally {
        await client.end();
    }
}

updateData().catch(console.error);

解释

  1. 事务管理

    • 使用 BEGINCOMMIT 来确保所有更新操作作为一个整体完成。如果中间有错误,则通过 ROLLBACK 回滚事务,保证数据一致性。
  2. 错误处理

    • 在循环中捕获并处理可能的错误,确保每个更新操作都被正确处理。
  3. 日志记录

    • 添加日志记录,以便跟踪哪些迭代没有更新任何行。

通过这种方式,你可以确保在 Node.js 中执行批量更新操作时不会出现数据不一致的问题。希望这些示例代码和解释能帮助你解决问题!


掐指一算,是你的程序写得有问题

我想也多半是这样,但是……找不出来。一样都是运行sql,为什么两边跑出来结果会不一样

用回调,更新完一个callback更新下一个。

可以考虑每次更新后,select 一下,把值打印出来。程序跑起来,把输出存到log文件里。查log文件看哪里出错了。

根据你的描述,你在使用Node.js进行批量更新操作时遇到了部分字段为空的问题。这个问题可能与事务处理、查询条件或数据源有关。以下是一些可能的原因及解决方案:

可能的原因

  1. 事务管理:确保所有的SQL操作都在一个事务中执行,这样可以保证所有操作要么全部成功,要么全部回滚。
  2. 查询条件:检查子查询的条件是否匹配到正确的记录。
  3. 数据源问题:确保数据源中的数据是完整的且满足你的查询条件。

示例代码

为了帮助你更好地理解如何处理这种问题,这里提供一个示例代码,展示如何使用node-postgres库来执行事务并批量更新数据:

const { Pool } = require('pg');

const pool = new Pool({
  user: 'your-user',
  host: 'localhost',
  database: 'your-database',
  password: 'your-password',
  port: 5432,
});

async function updateData() {
  const client = await pool.connect();

  try {
    await client.query('BEGIN');

    for (let i = 0; i < 540; i++) {
      const sql = `
        UPDATE eagleeye_kpi_company 
        SET previous_1=(
          SELECT CAST(index_value AS FLOAT)
          FROM etms_kpi_index_company_value
          WHERE index_id='AvgDailyCallClientCount'
            AND month='201403'
            AND index_value!='-'
            AND tenant_id='nestle-uat'
            AND eagleeye_kpi_company.company_id=etms_kpi_index_company_value.company_id
        )
        WHERE eagleeye_kpi_company.kpi_id='KPI_06'
          AND eagleeye_kpi_company.tenant_id='nestle-uat';
      `;
      await client.query(sql);
    }

    await client.query('COMMIT');
  } catch (err) {
    console.error('Error executing query', err.stack);
    await client.query('ROLLBACK');
  } finally {
    client.release();
  }
}

updateData().catch(console.error);

关键点解释

  1. 事务管理:在事务中执行所有更新操作,确保要么全部成功,要么全部失败。
  2. 循环更新:使用循环来批量更新数据。
  3. 错误处理:在出现错误时回滚事务,并释放数据库连接。

希望这些信息对你有所帮助!如果还有其他具体问题,请随时补充。

回到顶部