如何在Sequelize中调用带输出参数的存储过程并获取ERRCODE
在Sequelize中调用Oracle存储过程DTD.CSM_MIGRATE的正确方式
核心思路
Sequelize本身没有专门封装Oracle存储过程的调用API,需要通过sequelize.query()执行PL/SQL块来处理输入输出参数,以下是两种可靠的实现方式:
方式一:使用Sequelize原生Query方法
这种方式符合Sequelize框架的使用习惯,无需直接操作数据库连接:
const { Sequelize, DataTypes } = require('sequelize'); // 假设你已经初始化了sequelize实例 // const sequelize = new Sequelize(/* 连接配置 */); async function invokeMigrateProc() { try { // 定义输入参数 const inputVals = { p_id_equip: 1001, // 替换为实际业务值 p_fil_id: 2024, // 替换为实际业务值 p_mode: 'NORMAL', // 替换为实际业务值 p_is_pool: false // 替换为实际业务值 }; // 定义参数绑定(包含输出参数的类型和方向) const replacements = { ...inputVals, p_errcode: { type: DataTypes.INTEGER, dir: Sequelize.QueryTypes.OUT }, p_errtxt: { type: DataTypes.STRING(255), dir: Sequelize.QueryTypes.OUT } }; // 执行PL/SQL块调用存储过程 await sequelize.query( `BEGIN DTD.CSM_MIGRATE( :p_id_equip, :p_fil_id, :p_mode, :p_is_pool, :p_errcode OUT, :p_errtxt OUT ); END;`, { replacements, type: Sequelize.QueryTypes.RAW } ); // 从绑定对象中取出输出参数值 const errcode = replacements.p_errcode; const errtxt = replacements.p_errtxt; console.log('返回错误码:', errcode); console.log('返回错误信息:', errtxt); return { errcode, errtxt }; } catch (err) { console.error('调用存储过程失败:', err); throw err; } }
关键注意点
- PL/SQL块语法:必须用
BEGIN ... END;包裹存储过程调用,Oracle要求通过PL/SQL块处理输出参数,单纯的CALL语句无法直接捕获输出值。 - 输出参数配置:必须指定
dir: Sequelize.QueryTypes.OUT标记参数为输出类型,同时匹配存储过程定义的参数类型(比如DataTypes.INTEGER对应Oracle的NUMBER类型)。 - 参数顺序:PL/SQL块中的参数顺序必须和存储过程定义的参数顺序完全一致,Oracle存储过程默认按位置绑定参数。
方式二:直接使用oracledb底层API
如果需要更精细的参数控制,可以直接操作Sequelize管理的数据库连接,使用oracledb原生语法:
const { Sequelize } = require('sequelize'); const oracledb = require('oracledb'); // 假设已初始化sequelize实例 // const sequelize = new Sequelize(/* 连接配置 */); async function invokeMigrateProc() { let connection; try { // 从Sequelize连接池获取连接 connection = await sequelize.connectionManager.getConnection(); // 定义参数绑定,包含输入和输出参数 const binds = { p_id_equip: 1001, p_fil_id: 2024, p_mode: 'NORMAL', p_is_pool: false, p_errcode: { dir: oracledb.BIND_OUT, type: oracledb.NUMBER }, p_errtxt: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 255 } }; // 执行PL/SQL块 await connection.execute( `BEGIN DTD.CSM_MIGRATE( :p_id_equip, :p_fil_id, :p_mode, :p_is_pool, :p_errcode, :p_errtxt ); END;`, binds ); // 取出输出参数值 const errcode = binds.p_errcode.value; const errtxt = binds.p_errtxt.value; console.log('返回错误码:', errcode); console.log('返回错误信息:', errtxt); return { errcode, errtxt }; } catch (err) { console.error('调用存储过程失败:', err); throw err; } finally { // 务必释放连接回池 if (connection) await connection.release(); } }
关键注意点
- 连接管理:必须在
finally块中释放连接,避免连接池耗尽。 - oracledb类型匹配:使用
oracledb.NUMBER、oracledb.STRING等原生类型,确保和Oracle存储过程的参数类型完全匹配。 - 字符串参数长度:对于输出字符串参数,需要指定
maxSize,否则可能截断返回的错误信息。
常见排查方向
- 检查参数类型是否和存储过程定义一致(比如
p_is_pool如果是Oracle的BOOLEAN类型,Sequelize中用DataTypes.BOOLEAN)。 - 确认Sequelize和
oracledb驱动版本兼容,建议使用最新稳定版。 - 验证输入参数的取值范围是否符合存储过程的要求(比如数值类型是否超出范围、字符串长度是否超限)。
内容的提问来源于stack exchange,提问作者AlexHeadGU
相关产品推荐
相关产品推荐

