node-oracledb提供错误:NJS-044:在执行存储过程的过程中,在此上下文中不应使用命名的JSON对象

时间:2019-06-04 10:19:31

标签: node.js node-oracledb

我遇到了使用node-oracledb npm (“ oracledb”:“ ^ 3.1.2”)(“ @ types / oracledb”调用oracle db存储过程的问题: “ ^ 3.1.0”)插入node.js应用程序。该存储过程分别接受3个输入参数,其类型为string,oracleDB类型的字符串和数组。但是,在传递数据库类型的最后一个参数时,node.js应用程序将引发“ NJS-044:在此上下文中不希望使用命名的JSON对象”的异常。


// DB payload
let obj = {
        tableOwner: 'Mr X',
        tableName: 'Demo',
        retentionData: this.CreateArrayFromJSONObject(array_of_data)
        }

// DB procedure
let procedure: string = `BEGIN PKG_ARCHIVAL_TOOL.P_RETENTION_POLICY_CREATE(:tableOwner, :tableName, :retentionData); END;`;

/// DB execution function call
DBService.getInstance().ExecuteDBProcedureRequest(procedure, userPolicyJSON);

// DB executing
public ExecuteDBProcedureRequest = (procedure: string, inputBody: any) : Promise<any> => {
        return new Promise((resolve, reject) => {
            DBConn.execute(procedure, inputBody, { autoCommit: true}, (err: oracledb.DBError, result: oracledb.Result) => {
                if(err) {
                    reject(err);
                }
                if(result) {
                    resolve(Utils.CreateJSONObject(result));
                }
            })
        });
    }

// SQL procedure call
PKG_ARCHIVAL_TOOL.P_RETENTION_POLICY_CREATE(
                        P_TABLE_OWNER => P_TABLE_OWNER,
                        P_TABLE_NAME => P_TABLE_NAME,
                        P_RETEN_DATA => V_DATA,
                        P_ID => V_ID,
                        P_OUT => V_OUT
                );

P_RETEN_DATA is a table of a record:-
Record - TYPE R_RETENTION_POLICY_DEF IS RECORD(
        COLUMN_NAME    VARCHAR2(40) NOT NULL DEFAULT ' ',
        COLUMN_POS     NUMBER       NOT NULL DEFAULT 1,
        COLUMN_TYPE    VARCHAR2(10) NOT NULL DEFAULT 'NUMBER',
        OPERATOR       VARCHAR2(10) NOT NULL DEFAULT '=',
        GATE           VARCHAR2(10) DEFAULT NULL,
        BRAC_ST        NUMBER       DEFAULT 0,
        BRAC_ED        NUMBER       DEFAULT 0
);
Table :- TYPE T_RETENTION_POLICY_DEF IS TABLE OF R_RETENTION_POLICY_DEF;

array_of_data = [["FNAME, 1, "VARCHAR2", ">", "OR", 0, 0], ["LNAME, 1, "VARCHAR2", "=", "AND", 0, 0]]

1 个答案:

答案 0 :(得分:0)

绑定到记录仅在正在开发的here的node-oracledb 4中起作用。

您的代码还可能存在其他问题(PL / SQL调用中的参数数量,试图将某种数组传递给记录等)。

node-oracledb 3.1的一般解决方案是使用包装PL / SQL块,您可以将允许的类型绑定到其中。然后,该包装器块将这些值按摩到一条记录中,并调用目标过程P_RETENTION_POLICY_CREATE。

给出此SQL:

set echo on

create or replace package rectest as
  type rectype is record (name varchar2(40), pos number);
  procedure myproc (p_in in rectype, p_out out rectype);
end rectest;
/
show errors

create or replace package body rectest as
  procedure myproc (p_in in rectype, p_out out rectype) as
  begin
    p_out := p_in;
  end;
end rectest;
/
show errors

您会这样称呼它:

// Node-oracledb 3.1
'use strict';

const oracledb = require('oracledb');
const config = require('./dbconfig.js');

let sql, binds, options, result;

async function run() {
  let connection;

  try {
    connection = await oracledb.getConnection(config);

    sql =
      `declare
         i_r rectest.rectype;  -- input record
         o_r rectest.rectype;  -- output record
       begin
         i_r.name := :i_nm;
         i_r.pos := :i_ps;
         rectest.myproc(i_r, o_r);
         :o_nm := o_r.name;
         :o_ps := o_r.pos;
       end;`;

    binds = [
      {i_nm: 'def', i_ps: 456},
      {i_nm: 'ghi', i_ps: 789},
    ];

    const options = {
      bindDefs:
      { i_nm: { type: oracledb.STRING, maxSize: 40 },
        i_ps: { type: oracledb.NUMBER },
        o_nm: { type: oracledb.STRING, maxSize: 40, dir: oracledb.BIND_OUT },
        o_ps: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT }
      }
    };

    result = await connection.executeMany(sql, binds, options);
    console.log(result);


  } catch (err) {
    console.error(err);
  } finally {
    if (connection) {
      try {
        await connection.close();
      } catch (err) {
        console.error(err);
      }
    }
  }
}

run();

输出为

{
  outBinds: [ { o_nm: 'def', o_ps: 456 }, { o_nm: 'ghi', o_ps: 789 } ]
}