在用C#调用Oracle的存储过程时发生一个错误:
“ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小 ORA-06512: 在 "HAJYWEB.P_INSERT_RESHALL", line 4 ORA-06512: 在 line 1”
存储过程如下:
create or replace procedure P_TEST(lsh in varchar2,v_ret out varchar2,v_msg out varchar2) is
begin
// insert into prc_log (prc_name,prc_time,ywlsh) values('p_reshall',to_char(sysdate,'yyyy-MM-dd hh:mm:ss'),lsh);
v_ret:='2';
v_msg:='这是一个成功的执行结果';
end P_TEST;
有一个传入参数,两个输出参数。
跟踪了半天后发现如果输出参数的值的大小超过初始值,就会引发这个问题。例如:v_ret初始化时有4位,那返回时就不能超过4位。
google了下,http://www.dotblogs.com.tw/cliffliu/archive/2010/12/08/19992.aspx 这位仁兄提供了两种解决方法:
1.在存储过程中增加 nocopy 关键字,很可惜,试了后还是报错。
2.在初始化参数时指定 size,这个方法是可行的,但在我的项目中,由于是一个通用的SQLHelper,其中的参数是使用的IDataParameter接口,这个接口没有size属性,也只好作罢。
解决方法:
实在没有办法,只好在调用存储过程时,预先初始化一个长字符串进去,达到指定size的要求。
string tmpS = "";
tmpS= tmpS.PadLeft(50,'1');
******************分割线*****************************
上面的解决方法很可怜吧,哈哈
新的解决方法:把 IDataParameter 换成IDbDataParameter就可以了,
可以看下IDbDataParameter的定义就知道了,哈哈哈哈
// 摘要:
// 由 Visual Basic .NET 数据设计器使用,用来向 Command 对象表示一个参数,以及向该对象的 System.Data.DataSet
// 列映射表示参数(可选)。
public interface IDbDataParameter : IDataParameter
{
// 摘要:
// 指示数值参数的精度。
//
// 返回结果:
// 用于表示数据提供程序 Parameter 对象的 Value 属性的数字的最大位数。默认值为 0,它表示由数据提供程序设置 Value 的精度。
byte Precision { get; set; }
//
// 摘要:
// 指示数值参数的小数位数。
//
// 返回结果:
// 要将 System.Data.OleDb.OleDbParameter.Value 解析为的小数位数。默认值为 0。
byte Scale { get; set; }
//
// 摘要:
// 参数的大小。
//
// 返回结果:
// 列中数据的最大大小(以字节为单位)。从参数值推断默认值。
int Size { get; set; }
}