node-oracledb 从 PL/SQL 过程中同时获取 return 和输出值的问题

Problem with node-oracledb getting both return and out values from a PL/SQL procedure

下午好,我在 oracle 数据库中存储了这个函数定义:

CREATE OR REPLACE FUNCTION GET_INFO(id IN VARCHAR2,
account IN VARCHAR2,
info out INFO_ITEM)
RETURN NUMBER
AS
rv NUMBER:= 0;
...

我正在尝试使用 node-oracledb 模块获取 return 和输出值:

const sql = `
          DECLARE
          info INFO_ITEM;
          result NUMBER;
          BEGIN 
            :result := GET_INFO(:id, :account, info);                     
          END;
`;
const params = {
          id: '123',
          account: '123',
          result: { dir: BIND_OUT },
        };

const options = {
    outFormat: oracledb.OUT_FORMAT_OBJECT,
};

oracleConnection.execute(sql, params, options)

我得到的查询结果很好 ({outBinds: {result: 1}}),但在弄清楚如何获取输出值时遇到了问题。我对 PL/SQL 查询还很陌生,所以如果有人能给我建议如何处理这个问题,我将不胜感激。

查看node-oracledb示例https://github.com/oracle/node-oracledb/blob/master/examples/plsqlfunc.js and https://github.com/oracle/node-oracledb/blob/master/examples/plsqlrecord.js

同时查看 node-oracledb documentation

首先,您需要使用另一个绑定变量 return 函数结果。诀窍是设置类型——我不知道 INFO_ITEM 是什么。这样的事情可能会奏效:

const sql = `
          BEGIN
            :result := GET_INFO(:id, :account, :info);
          END;
`;
const params = {
          id: '123',
          account: '123',
          info: { dir: oracledb.BIND_OUT, type: "THEOWNINGSCHEMANAME.INFO_ITEM" },
          result: { dir: oracledb.BIND_OUT, type: oracledb.NUMBER }
        };

const options = {
    outFormat: oracledb.OUT_FORMAT_OBJECT,
};

oracleConnection.execute(sql, params, options)

注意,文档说:

When handling multiple objects of the same type, then use fully qualified names like “MDSYS.SDO_GEOMETRY” instead of “SDO_GEOMETRY”. Alternatively retain, and use, the prototype object returned by connection.getDbObjectClass(). Node-oracledb will cache type information using the type’s fully qualified name as the key to avoid the expense of a round-trip, when possible. Each connection has its own cache.

另一种方法(实际上可能具有性能优势)是 return info 的各个部分作为标量绑定值。类似于:

const sql = `
          DECLARE
          info INFO_ITEM;
          result NUMBER;
          BEGIN
            :result := GET_INFO(:id, :account, info);
            :v1 := info.whatever;
          END;
`;
const params = {
          id: '123',
          account: '123',
          result: { dir: oracledb.BIND_OUT,  oracledb.NUMBER },
          v1:  { dir: oracledb.BIND_OUT,  oracledb.NUMBER },
        };

const options = {
    outFormat: oracledb.OUT_FORMAT_OBJECT,
};

oracleConnection.execute(sql, params, options)

关于术语,PL/SQL 块 不是 查询。查询类似于 SELECT 语句。