You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js脚本无财务数据时无法插入MySQL问题求助

问题排查:无财务数据时无法插入全0记录到MySQL

我是JS和Node.js初学者,编写的脚本从MySQL查询公司列表,针对每家公司的2018-2021年调用第三方API获取财务数据;当存在财务数据时可正常插入Date_Financiare表,但无财务数据时无法插入全0值的记录,其余功能均正常。

相关代码

var mysql = require('mysql');
fetch = require('node-fetch');

var connection = mysql.createConnection({
  host: "host.ip",
  user: "user_name",
  password: "pass_word",
  database: "db_db"
});
var years_to_scrape = [2021, 2020, 2019, 2018];

connection.query("SELECT t1.CUI,t1.Denumire_Companie,Reg_Com,Status,Localitate FROM Date_Companii as t1 LEFT JOIN Date_Financiare as t2 ON t2.cui = t1.cui WHERE t2.AN IS NULL ORDER by t1.CUI DESC LIMIT 3", function(error, results, fields) {
  if (error) { return console.error(error.message);}

  var db_results = results;

  for (i in db_results) {
    var one_after_another = JSON.parse(JSON.stringify(db_results[i]));
    console.log(one_after_another.CUI);

    for (i in years_to_scrape){
      var url = 'https://webservicesp.anaf.ro/bilant?an=' + years_to_scrape[i]+ '&cui=' + one_after_another.CUI;
      
      fetch(url)
        .then(res => res.json())
        .then (json => {
          console.log(json)
          var r = json;
          console.log(r)

          var indicatori = JSON.parse(JSON.stringify(r.i))
          console.log (indicatori)

          if (indicatori.length==0){
            connection.query('INSERT INTO Date_Financiare(CUI,AN,Numar_Salariati,Pierdere_Neta,Profit_Net,Pierdere_Bruta,Profit_Brut,Cheltuieli_Totale,Venituri_Totale,Cifra_De_Afacere_Neta,Patrimoniul_Regiei,Capital_Subscris_Varsat,Capitaluri_Total,Provizioane,Venituri_In_Avans,Datorii,Cheltuieli_In_Avans,Casa_Si_Conturi,Creante,Stocuri,Active_Circulante,Active_Mobilizate,CAEN) VALUES ('+cuiul+","+anul+',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);', function(error,results,fields) {
              if (error) { /*return console.error(error.message)*/;}
              if(results){/*return console.log("results");*/}
              if(fields){/*return console.log("fields");*/}
              console.log("Inserted into DB");
            })
          } else {
            var anul = r.an;
            console.log("Anul: "+ anul)
            var cuiul = r.cui;
            console.log("CUI: "+ cuiul)
            var caen = r.caen;
            console.log("CAEN: "+caen)

            for (z in indicatori){
              if(indicatori[z].indicator === "I1"){
                var valoare_active_mobilizate = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I2"){
                var valoare_active_circulante = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I3"){
                var valoare_stocuri = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I4"){
                var valoare_creante = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I5"){
                var valoare_casa_si_conturi = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I6"){
                var valoare_cheltuieli_in_avans = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I7"){
                var valoare_datorii = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I8"){
                var valoare_venituri_in_avans = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I9"){
                var valoare_provizioane = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I10"){
                var valoare_capitaluri_total = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I11"){
                var valoare_capital_subscris_varsat = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I12"){
                var valoare_patrimoniul_regiei = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I13"){
                var valoare_cifra_de_afacere_neta = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I14"){
                var valoare_venituri_totale = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I15"){
                var valoare_cheltuieli_totale = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I16"){
                var valoare_profit_brut = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I17"){
                var valoare_pierdere_bruta = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I18"){
                var valoare_profit_net = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I19"){
                var valoare_pierdere_neta = indicatori[z].val_indicator;
              } else if(indicatori[z].indicator === "I20"){
                var valoare_numar_salariati = indicatori[z].val_indicator;
              } else {Console.log("Error")};
              
              connection.query("INSERT INTO Date_Financiare(CUI,AN,Numar_Salariati,Pierdere_Neta,Profit_Net,Pierdere_Bruta,Profit_Brut,Cheltuieli_Totale,Venituri_Totale,Cifra_De_Afacere_Neta,Patrimoniul_Regiei,Capital_Subscris_Varsat,Capitaluri_Total,Provizioane,Venituri_In_Avans,Datorii,Cheltuieli_In_Avans,Casa_Si_Conturi,Creante,Stocuri,Active_Circulante,Active_Mobilizate,CAEN) VALUES ("+cuiul+","+anul+","+valoare_numar_salariati+","+valoare_pierdere_neta+","+valoare_profit_net+","+valoare_pierdere_bruta+","+valoare_profit_brut+","+valoare_cheltuieli_totale+","+valoare_venituri_totale+","+valoare_cifra_de_afacere_neta+","+valoare_patrimoniul_regiei+","+valoare_capital_subscris_varsat+","+valoare_capitaluri_total+","+valoare_provizioane+","+valoare_venituri_in_avans+","+valoare_datorii+","+valoare_cheltuieli_in_avans+","+valoare_casa_si_conturi+","+valoare_creante+","+valoare_stocuri+","+valoare_active_circulante+","+valoare_active_mobilizate+","+caen+");", function(error,results,fields) {
                if (error) { /*return console.error(error.message);*/}
              })
            }
          }
        })
    }
  });
});

数据库查询结果示例

[
  RowDataPacket {
    CUI: 2147483647,
    Denumire_Companie: 'Company Name 1',
    Reg_Com: 'F40/2569/2003',
    Status: 1048,
    Localitate: null
  },
  RowDataPacket {
    CUI: 45892171,
    Denumire_Companie: 'Company Name 2',
    Reg_Com: 'J6/342/2022',
    Status: 1048,
    Localitate: 'Municipiul Bistriţa'
  },
  RowDataPacket {
    CUI: 45892163,
    Denumire_Companie: 'Company Name 3',
    Reg_Com: 'J6/340/2022',
    Status: 1048,
    Localitate: 'Loc. Viişoara'
  }
]

问题原因分析

  1. 变量未定义:在无财务数据的分支中,cuiul和anul两个变量未被初始化,仅在有数据的else分支里定义。拼接SQL时会生成VALUES (undefined, undefined, 0,...)的无效语句,触发SQL语法错误。
  2. 错误被屏蔽:插入操作的错误处理代码被注释,导致无法看到具体报错信息,无法直接定位问题。
  3. 循环变量冲突:外层遍历公司的循环和内层遍历年份的循环都使用变量i,会导致变量覆盖,异步操作中可能获取错误的年份或公司数据。
  4. SQL拼接风险:直接将变量拼接到SQL字符串中,既容易出现语法错误,还存在SQL注入安全隐患。

修复方案

1. 补全无数据分支的变量定义

从当前循环的公司和年份中获取CUI和年份值,无需依赖API返回结果:

// 在无数据分支开头添加变量定义
var cuiul = one_after_another.CUI;
var anul = years_to_scrape[yearIndex]; // 注意修改内层循环变量名

2. 使用参数化查询

用占位符?代替直接拼接变量,传递参数数组,避免语法错误和SQL注入:

// 无数据分支的插入语句改为参数化查询
const insertSql = `INSERT INTO Date_Financiare(CUI,AN,Numar_Salariati,Pierdere_Neta,Profit_Net,Pierdere_Bruta,Profit_Brut,Cheltuieli_Totale,Venituri_Totale,Cifra_De_Afacere_Neta,Patrimoniul_Regiei,Capital_Subscris_Varsat,Capitaluri_Total,Provizioane,Venituri_In_Avans,Datorii,Cheltuieli_In_Avans,Casa_Si_Conturi,Creante,Stocuri,Active_Circulante,Active_Mobilizate,CAEN) VALUES (?, ?, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)`;
connection.query(insertSql, [cuiul, anul], function(error, results, fields) {
  if (error) { return console.error(error.message); } // 取消错误输出注释
  console.log("Inserted into DB");
});

3. 修复循环变量冲突

将内层遍历年份的循环变量从i改为yearIndex,避免覆盖外层循环的i:

for (yearIndex in years_to_scrape){
  // ... 内层循环逻辑
}

4. 启用错误日志

取消错误处理代码的注释,插入失败时能直接在控制台看到错误信息,方便调试。

5. 优化异步流程(可选)

使用async/await替代嵌套回调,让代码更易读,避免异步循环中的变量作用域问题:

// 将外层回调改为async函数
connection.query("SELECT ...", async function(error, results, fields) {
  if (error) { return console.error(error.message); }
  for (const company of db_results) {
    for (const year of years_to_scrape) {
      const url = `https://webservicesp.anaf.ro/bilant?an=${year}&cui=${company.CUI}`;
      const res = await fetch(url);
      const json = await res.json();
      const indicatori = json.i || [];
      
      if (indicatori.length === 0) {
        // 插入全0记录
        const insertSql = `INSERT INTO Date_Financiare(CUI,AN,Numar_Salariati,...) VALUES (?, ?, 0,...)`;
        await new Promise((resolve, reject) => {
          connection.query(insertSql, [company.CUI, year], (err) => {
            if (err) reject(err);
            else resolve();
          });
        });
      } else {
        // 处理有数据的情况...
      }
    }
  }
});

内容的提问来源于stack exchange,提问作者Alex G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:03:20