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

Node.js用createPool()连接Oracle报NJS-047错误解决方案咨询

错误原因
  • 异步逻辑未等待:config.init()是异步函数,app.js的路由处理函数没有使用await等待执行结果,导致oracledb.createPool()还没完成创建连接池的操作,后续getConnection()就已经执行,找不到默认连接池抛出NJS-047错误。
  • 连接池重复创建:当前逻辑每次请求/getCustomerName接口都会调用一次init()尝试创建新的连接池,连接池全局只需初始化一次即可,重复创建不仅性能差还会引发状态异常。
  • 查询结果未返回:dostuff函数执行查询后没有将结果return,上层调用即使等待执行完成也拿不到查询数据,所以接口返回空内容。
修复方案

第一步:修改config.js,拆分连接池初始化和查询逻辑

const oracledb = require('oracledb')
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT

// 初始化连接池,服务启动时调用一次即可
const initPool = async function () {
  try {
    await oracledb.createPool({
      user: 'almat',
      password: 'almat789456123',
      connectString: '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=xepdb1)))'
    })
    console.log('Connection pool started')
  } catch (err) {
    console.error('initPool() error: ' + err.message)
    throw err // 抛出错误让上层感知初始化失败
  }
}

// 单独封装查询方法,每次请求调用
const executeQuery = async function(query, binds = []) {
  let connection
  try {
    connection = await oracledb.getConnection()
    const options = { outFormat: oracledb.OUT_FORMAT_OBJECT }
    const result = await connection.execute(query, binds, options)
    return result // 返回查询结果
  } catch (err) {
    console.error('executeQuery error:', err)
    throw err
  } finally {
    if (connection) {
      try {
        await connection.close()
      } catch (err) {
        console.error('connection close error:', err)
      }
    }
  }
}

async function closePoolAndExit () {
  console.log('\nTerminating')
  try {
    await oracledb.getPool().close(10)
    console.log('Pool closed')
    process.exit(0)
  } catch (err) {
    console.error(err.message)
    process.exit(1)
  }
}

process
  .once('SIGTERM', closePoolAndExit)
  .once('SIGINT', closePoolAndExit)

module.exports = { initPool, executeQuery }

第二步:修改app.js,启动时初始化连接池,路由添加异步等待

const express = require('express');
const { initPool, executeQuery } = require('./utils/config');

const app = express();

app.set('view engine', 'ejs')

app.get('/', function (req, res) {
  return res.render('index')
})

app.get('/login', function (req, res) {
  return res.render('login')
})

// 路由处理函数加async关键字
app.get('/getCustomerName', async function (req, res) {
  try {
    const query = 'SELECT firstname FROM customer WHERE :b = 1'
    const binds = [1]
    const result = await executeQuery(query, binds) // 等待查询结果
    return res.send(result)
  } catch (err) {
    return res.status(500).send({ error: err.message })
  }
})

// 先初始化连接池,成功后再启动服务
async function startServer() {
  try {
    await initPool()
    app.listen(3000, function () {
      console.log('Server running at port 3000')
    })
  } catch (err) {
    console.error('Server start failed:', err)
    process.exit(1)
  }
}

startServer()

module.exports = app

修复说明

  • 连接池改为服务启动时一次性初始化,避免每次请求重复创建
  • 所有异步操作都添加await等待执行完成,保证时序正确
  • 封装独立的查询方法,直接返回查询结果,接口可以正常拿到数据返回给前端
  • 添加异常捕获,接口异常时返回明确的错误信息,方便排查

内容的提问来源于stack exchange,提问作者Almat Kaipzhanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:18:03