C# Oracle numeric or value error: character string buffer too small 注意事项

在调用Oracle存储过程时遇到【ORA-06502: PL/SQL: numeric or value error: character string buffer too small】错误,问题出在参数顺序不匹配。调整C#代码中参数添加顺序以匹配存储过程定义,错误解决。提示开发者在调用第三方存储过程时,应确保参数顺序正确。
部署运行你感兴趣的模型镜像

背景

最近手头上有比较多项目与Oracle相关,并且需要调用一些Oracle的自定义方法和函数, 最近接触的一个存储过程,无论怎么调用都会出现 【ORA-06502: PL/SQL: numeric or value error: character string buffer too small】 的错误, 而且这个存储过程并非我司同事编写,非常不好调试,最后发现是参数顺序问题, 调整为完全与存储过程定义一致之后,问题解决。

详细描述

这个storeproc大概是这个样子的

     sp_demo(O_ERROR_MESSAGE, O_ERROR_CODE, I_DC_CODE, I_STORE_CODE, I_ADJ_NO) ;

返回的是一个NUMBER类型。 (原来是BOOLEAN,但是众所周知.NET 与ORACLE 的BOOLEAN类型实在有点不太对付, 所以改成了NUMBER).
参数大概是这样子的

O_ERROR_MESSAGE INOUT VARCHAR2(4000)
O_ERROR_CODE INOUT NUMBER(10)
I_DC_CODE IN VARCHAR2(10)
I_STORE_CODE IN VARCHAR2(20)
I_ADJ_NO IN NUMBER(10)

而我的C# Code 大概是这样子

OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "sp_demo";
cmd.CommandType = CommandType.StoredProcedure;
OracleParameter p1 = new OracleParameter("I_DC_CODE ", OracleDbType.Varchar2,10);
OracleParameter p2 = new OracleParameter("I_STORE_CODE ", OracleDbType.Varchar2,20);
OracleParameter p3 = new OracleParameter("I_ADJ_NO ", OracleDbType.Decimal, 10);
OracleParameter p4 = new OracleParameter("O_ERROR_MESSAGE", OracleDbType.Varchar2,4000);
OracleParameter p5 = new OracleParameter("O_ERROR_CODE ", OracleDbType.Decimal, 10);
cmd.Parameters.Add(p1);
cmd.Parameters.Add(p2);
cmd.Parameters.Add(p3);
cmd.Parameters.Add(p4);
cmd.Parameters.Add(p5);

看上去没什么大问题, 然而无论怎么执行,都会提示

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

既然提示长度问题, 我全部放长了一遍, 都不行。 怀疑了一下O_ERROR_MESSAGE 的INOUT和长度问题, 发现之前另一个项目也有类似的存储过程,调用没问题。
找了一下stackoverflow, 提示的都只有类似如下的

if you decalre it like bellow, directly in the constructor it DOSEN’T work:cmd.Parameters.Add(new OracleParameter("myretval", OracleDbType.Long, 10, ParameterDirection.ReturnValue));

if you declare it like this it works: OracleParameter retval = (new OracleParameter("myretval", OracleDbType.Long, 10); retval.Direction = ParameterDirection.ReturnValue; cmd.Parameters.Add(retval);

然而上面的都没用。

再仔细比对了一下, 发现一个比较可疑的地方, 是存储过程的参数顺序, 跟我代码里面的添加顺序 是不一致的。 虽然一般来说都用参数名去绑定输入,但是死马当活马医, 我调整了一下顺序,按照完全一致的顺序去添加, 即调整为

OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "sp_demo";
cmd.CommandType = CommandType.StoredProcedure;
OracleParameter p1 = new OracleParameter("I_DC_CODE ", OracleDbType.Varchar2,10);
OracleParameter p2 = new OracleParameter("I_STORE_CODE ", OracleDbType.Varchar2,20);
OracleParameter p3 = new OracleParameter("I_ADJ_NO ", OracleDbType.Decimal, 10);
OracleParameter p4 = new OracleParameter("O_ERROR_MESSAGE", OracleDbType.Varchar2,4000);
OracleParameter p5 = new OracleParameter("O_ERROR_CODE ", OracleDbType.Decimal, 10);
//将p4/p5调整到前面, 和存储过程定义一致
cmd.Parameters.Add(p4);
cmd.Parameters.Add(p5);
cmd.Parameters.Add(p1);
cmd.Parameters.Add(p2);
cmd.Parameters.Add(p3);

居然还真的行。 因为这个存储过程不是自己人写的,初步怀疑里面有地方并非用参数名字去调用, 而是按照@1234这样的顺序的那种参数进行调用,当入参不完全按照顺序的时候, 顺序参数的长度其实与定义不一致,导致出现了这个提示。
但是SQL SERVER 我真的从来没有遇到过这个问题, 所以我一度怀疑并不是Oracle的问题, 而是这个存储过程的写法问题, 然而目前我又没有办法进行验证。
只能说, 提醒自己,永远都按照第三方给的函数的顺序去添加吧, 不知道还有什么奇怪的事情呢……

您可能感兴趣的与本文相关的镜像

Yolo-v8.3

Yolo-v8.3

Yolo

YOLO(You Only Look Once)是一种流行的物体检测和图像分割模型,由华盛顿大学的Joseph Redmon 和Ali Farhadi 开发。 YOLO 于2015 年推出,因其高速和高精度而广受欢迎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值