背景
最近手头上有比较多项目与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的问题, 而是这个存储过程的写法问题, 然而目前我又没有办法进行验证。
只能说, 提醒自己,永远都按照第三方给的函数的顺序去添加吧, 不知道还有什么奇怪的事情呢……

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

被折叠的 条评论
为什么被折叠?



