【问题标题】:Problem with pass params to stored procedure in oracledb node.js module将参数传递给 oracledb node.js 模块中的存储过程的问题
【发布时间】:2022-01-10 08:32:19
【问题描述】:

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

(节点:6952)UnhandledPromiseRejectionWarning:错误:ORA-06502:PL/SQL:数字或值错误

这是程序:

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。

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

【问题讨论】:

    标签: node.js oracle express stored-procedures node-oracledb


    【解决方案1】:

    19c 对我来说似乎很好。是 IN 还是 OUT 绑定的问题?我知道在为客户端和服务器混合小端和大端时,布尔绑定存在一个问题。这已在 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() 是否返回NaN。如果你尝试为in_id 绑定它,你会得到DPI-1055: value is not a number (NaN) and cannot be used in Oracle numbers

    【讨论】:

    • 谢谢,你指出了正确的方向,问题是没有参数,它返回布尔值。我更新了我的存储过程(返回数字值)并且一切正常:)
    猜你喜欢
    • 2014-11-19
    • 2016-04-05
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多