将参数传递给 oracledb node.js 模块中的存储过程的问题

Problem with pass params to stored procedure in oracledb node.js module

我正在 Node.js 上创建项目项目并使用 oracledb 模块。我应该调用带参数的存储过程,但是当我尝试将数字参数传递给该过程时,出现此错误:

(node:6952) UnhandledPromiseRejectionWarning: Error: ORA-06502: PL/SQL: numeric or value error

这是程序:

create or replace procedure delete_song
(s_id in number,  procedure_result out boolean) is
begin
delete from PLAYLIST_SONGS where SONG_ID = s_id;
delete  from SONG where ID = s_id;
procedure_result:=true;
commit ;
exception when others
    then
procedure_result:= false;
rollback;
end;

我在 Node.js 应用程序中执行程序的代码:

router.delete("/:id", async (req, res) => {
  const connection = await orcldb.getConnection(dbconf);

  let in_id;

  if (req.params.id === undefined) {
    throw new Error("Bad request");
  } else {
    in_id = parseInt(req.params.id);
  }

  console.info("id: ", in_id, typeof in_id);

  let procedureResult = await connection.execute(
    `
    BEGIN 
      DB_ADMIN.DELETE_SONG(:id, :ret);
     END;`,
    {
      id: in_id,
      ret: { dir: orcldb.BIND_OUT, type: orcldb.DB_TYPE_BOOLEAN },
    }
  );

  let result = procedureResult.outBinds.ret;

  if (!result) {
    throw new Error("Delete song failed");
  }

  resultSet.close();
  res.end("Success");
});

当我从 datagrip(例如)调用此过程时一切正常,脚本:

declare
    result boolean;
begin
    DB_ADMIN.DELETE_SONG(41, result);
end;

正确连接到数据库并获取数据。 我的数据库模式:

Database schema

Db 用户可以调用存储过程。 我正在使用 Oracle 12c。

我希望有人能帮助我,我很抱歉我的英语不好。

我觉得 19c 没问题。 IN 或 OUT 绑定有问题吗?我知道在为客户端和服务器混合小端和大端时,BOOLEAN 绑定存在一个问题。这已在 12.2 中修复。

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

if (process.platform === 'darwin') {
  oracledb.initOracleClient({libDir: process.env.HOME + '/Downloads/instantclient_19_8'});
}

async function run() {
  let connection;

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

    await connection.execute(
      `create or replace procedure delete_song
          (s_id in number, procedure_result out boolean) is
       begin
          procedure_result:=true;
       end;`);

    let in_id = 1;
    let procedureResult = await connection.execute(
      `BEGIN DELETE_SONG(:id, :ret); END;`,
      { id: in_id,
        ret: { dir: oracledb.BIND_OUT, type: oracledb.DB_TYPE_BOOLEAN },
      });

    let result = procedureResult.outBinds.ret;
    console.log(result);

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

run();

输出为:

$ node t.js
true

您的验证应检查是否 parseInt() returns NaN。如果您尝试为 in_id 绑定它,您将得到 DPI-1055: value is not a number (NaN) and cannot be used in Oracle numbers