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

Node.js调用Oracle 21c存储过程返回空数组,参数传递失败

问题:Oracle存储过程调用时客户端参数无法传递至服务端

环境

  • Oracle 21c
  • Node.js v20

问题描述

调用存储过程时客户端参数无法传递至服务端,但使用硬编码参数可正常返回结果。通过Postman携带查询参数测试,数据库中存在对应记录,但接口返回空数组。

相关代码

const oracledb = require('oracledb');

const mypw = ... // the hr schema password

async function getRecords(req, res) {
    let connection;

    // client inputs
    let p1 = req.query.p1;
    let p2 = req.query.p2;

    try {
        connection = await oracledb.getConnection({
            user: "myuser",
            password: mypw,
            connectString: "localhost/DB1"
        });

        const result = await connection.execute(
            `BEGIN myproc(:p1, :p2, :p_cursor); END;`,
            { // bind variables
                p1: { dir: oracledb.BIND_IN, type: oracledb.STRING },
                p2: { dir: oracledb.BIND_IN, type: oracledb.STRING },
                p_cursor: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
            },
            [],
        );
        console.log(result.rows);
        res.send(result.rows); // <-- empty array

    } catch (err) { // catches errors in getConnection and the query
        res.send(err);
    } finally {
        if (connection) {   // the connection assignment worked, must release
            try {
                await connection.release();
            } catch (e) {
                console.error(e);
            }
        }
    };
}

解决方案

问题出在绑定变量的定义上:你只指定了参数的方向和类型,但没有把客户端获取到的p1、p2实际值传递给绑定变量,导致存储过程接收到的是空参数,自然返回空结果。

另外原代码直接访问result.rows的方式错误,游标类型的输出参数需要单独处理才能获取数据。修正后的代码如下:

const oracledb = require('oracledb');

const mypw = ... // the hr schema password

async function getRecords(req, res) {
    let connection;

    // client inputs
    let p1 = req.query.p1;
    let p2 = req.query.p2;

    try {
        connection = await oracledb.getConnection({
            user: "myuser",
            password: mypw,
            connectString: "localhost/DB1"
        });

        const result = await connection.execute(
            `BEGIN myproc(:p1, :p2, :p_cursor); END;`,
            { // bind variables - 修正:传入实际参数值
                p1: { dir: oracledb.BIND_IN, type: oracledb.STRING, val: p1 },
                p2: { dir: oracledb.BIND_IN, type: oracledb.STRING, val: p2 },
                p_cursor: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
            },
            [],
        );
        // 处理游标获取数据
        const cursor = result.outBinds.p_cursor;
        const rows = await cursor.getRows();
        await cursor.close();
        
        console.log(rows);
        res.send(rows);

    } catch (err) { // catches errors in getConnection and the query
        res.send(err);
    } finally {
        if (connection) {   // the connection assignment worked, must release
            try {
                await connection.release();
            } catch (e) {
                console.error(e);
            }
        }
    };
}

如果不需要显式指定参数类型,也可以用更简洁的绑定写法(oracledb会自动推断类型和默认的IN方向):

{
    p1: p1,
    p2: p2,
    p_cursor: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:42:04