无法读取null [node-mssql]

时间:2017-10-30 09:40:51

标签: javascript node.js node-mssql

我正在尝试运行一个脚本,我从一个数据库中提取记录,然后将记录插入另一个数据库,但在插入步骤中,我继续遇到此错误8或9次重​​复。

我对node-mssql库并不是很熟悉,并且非常感谢能够对这里发生的事情有所了解!我附上了堆栈跟踪和脚本的副本。

  const sql = require('mssql')
        const humENV = require('../env').humENV
        const rbENV = require('../env').rbENV
        const logger = require('./logger')

        const getReviewHumanatic = async () => {
          try {
            let pool = await sql.connect(humENV.SQL_CONFIG)
            let req = await pool.request()
            .query(`
              WITH cte 
              AS (SELECT DISTINCT TOP 500 htaskid, 
                  ht.frn_leuserid, 
                  ht.frn_callid, 
                  ht.frn_hcatid, 
                  ht.frn_hcat_optionid, 
                  frn_lskinid, 
                  cq.duration_seconds, 
                  add_path, 
                  CASE 
                    WHEN call_queueid IS NULL THEN 3 
                    ELSE 1 
                  END AS status, 
                  CASE 
                    WHEN hcab_reviewid IS NULL THEN 0 
                    ELSE 1 
                  END AS HCAB 
                  FROM   htask ht 
                        LEFT JOIN call_queue cq 
                          ON ht.frn_callid = cq.frn_callid 
                        LEFT JOIN hcab_review hr 
                          ON hr.frn_callid = cq.frn_callid 
                            AND ht.frn_leuserid = hr.frn_leuserid) 
              SELECT Isnull(frn_callid, 0)       AS frn_callid,
                    Isnull(frn_hcatid, 0)        AS frn_hcatid, 
                    Isnull(HCAB, 0)              AS HCAB, 
                    Isnull(frn_hcat_optionid, 0) AS frn_hcat_optionid, 
                    Isnull(frn_lskinid, 0)       AS frn_lskinid, 
                    Isnull(frn_leuserid, 0)      AS frn_leuserid, 
                    Isnull(status, 0)            AS status, 
                    Isnull(duration_seconds, 0)  AS duration_seconds, 
                    Isnull(add_path, '')         AS add_path, 
                    Isnull(htaskid, 0)           AS htaskid 
              FROM   cte 
              ORDER BY frn_callid
              `)
            if (req.recordset.length !== 0) {
              console.log(req.recordset)
              logger.info('returning query records')
              return req.recordset
            }
            pool.close()
          } catch (err) {
            logger.error(err)
          }
        }

        const insertRebase = async (data) => {
          try {
            sql.close()
            let pool = await sql.connect(rbENV.SQL_CONFIG)
            for (let i = 0; i < data.length; i++) {
              console.log(data[i])
              let req = await pool.request()
              .input('frn_callid', sql.BigInt, data[i].frn_callid)
              .input('frn_categoryid', sql.Int, data[i].frn_hcatid)
              .input('HCAB', sql.Int, data[i].HCAB)
              .input('frn_answer_optionid', sql.Int, data[i].frn_hcat_optionid)
              .input('frn_leuserid', sql.Int, data[i].frn_leuserid)
              .input('frn_lskinid', sql.Int, data[i].frn_lskinid)
              .input('frn_statusid', sql.TinyInt, data[i].status)
              .input('reviewid', sql.Int, data[i].htaskid)
              .input('call_duration', sql.Int, data[i].duration_seconds)
              .input('HCAB_trigger', sql.VarChar, data[i].add_path)
              .query('SET IDENTITY_INSERT review ON; INSERT INTO review (frn_callid, frn_categoryid, HCAB, frn_answer_optionid, frn_leuserid, frn_lskinid, frn_statusid, reviewid, call_duration, HCAB_trigger) VALUES (@frn_callid, @frn_categoryid, @HCAB, @frn_answer_optionid, @frn_leuserid, @frn_lskinid, @frn_statusid, @reviewid, @call_duration, @HCAB_trigger)', function (err, recordset) {
                if (err) {
                  logger.error(err)
                  console.log(err)
                }
                pool.close()
              })
            }
          } catch (err) {
            logger.error(err)
          }
        }

        const initializeReview = async () => {
          try {
            const humData = await getReviewHumanatic()
            insertRebase(humData)
          } catch (err) {
            console.log(err)
          }
        }

        initializeReview()

我看了这个问题NPM MSSQL - error: uncaughtException: Cannot read property 'release' of null,但看起来没有一个确凿的解决方案。

堆栈错误跟踪:

stack trace

编辑: 自从我的原始帖子以来,我已将插入查询转换为预备语句:

const insertRebase = async (data) => {
  try {
    sql.close()
    let pool = await sql.connect(rbENV.SQL_CONFIG)
    for (let i = 0; i < data.length; i++) {

      let ps = new sql.PreparedStatement(pool)
      ps.input('frn_callid', sql.BigInt)
      ps.input('frn_categoryid', sql.Int)
      ps.input('HCAB', sql.Int)
      ps.input('frn_answer_optionid', sql.Int)
      ps.input('frn_leuserid', sql.Int)
      ps.input('frn_lskinid', sql.Int)
      ps.input('frn_statusid', sql.TinyInt)
      ps.input('reviewid', sql.Int)
      ps.input('call_duration', sql.Int)
      ps.input('HCAB_trigger', sql.VarChar)
      ps.prepare(`SET IDENTITY_INSERT review ON; INSERT INTO review (frn_callid, frn_categoryid, HCAB, frn_answer_optionid, frn_leuserid, frn_lskinid, frn_statusid, reviewid, call_duration, HCAB_trigger) VALUES (@frn_callid, @frn_categoryid, @HCAB, @frn_answer_optionid, @frn_leuserid, @frn_lskinid, @frn_statusid, @reviewid, @call_duration, @HCAB_trigger)`, err => {
        if (err) {
          console.log(err)
          logger.error(err)
        } else {
          ps.execute({frn_callid: data[i].frn_callid, frn_categoryid: data[i].frn_hcatid, HCAB: data[i].HCAB, frn_answer_optionid: data[i].frn_hcat_optionid, frn_leuserid: data[i].frn_leuserid, frn_lskinid: data[i].frn_lskinid, frn_statusid: data[i].status, reviewid: data[i].htaskid, call_duration: data[i].duration_seconds, HCAB_trigger: data[i].add_path}, (err, result) => {
            if (err) {
              console.log(err)
              logger.error(err)
            } else {
              ps.unprepare(err => {
                if (err) {
                  console.log(err)
                  logger.error(err)
                }
              })
            }
          })
        }
      })
    }
  } catch (err) {
    logger.error(err)
  }
}

我不确定为什么预备解决方案适用于以前的解决方案,但是准备好的声明解决方案似乎没有错误并正确插入所有记录。

至于sql.close()全局连接问题,是否正在执行

const getReviewHumanatic = async () => {
  try {
    let pool1 = await sql.connect(SQL_CONFIG1)
    let req = await pool1.request()
}

创建全局连接?我假设它正在创建一个本地连接,如果我做了

let pool2 = await sql.connect(SQL_CONFIG2)

它会创建一个单独的SQL连接,但似乎并非如此,因为在创建pool2之前,我无法在不执行sql.close()的情况下运行脚本。

我检查了node-mssql文档,看起来如果我没有池规范的请求,它将使用全局sql连接;也许这就是我的剧本发生了什么? https://www.npmjs.com/package/mssql#request

0 个答案:

没有答案