调用Oracle存储过程遇ORA-06502:宿主绑定数组过小(C#端排查)
ORA-06502: PL/SQL: numeric or value error: host bind array too small 问题解决
问题描述
调用Oracle存储过程读取字符串数组时触发以下错误:
ORA-06502: PL/SQL: numeric or value error: host bind array too small.
存储过程本身可正常运行,但通过C#调用时报错,推测为C#代码参数配置问题。
相关代码
C#调用代码
string[] myArray2 = new string[NoOfDay]; OracleString[] arrDays = null; OracleParameter P_result2 = new OracleParameter("UTILDAYS", OracleDbType.Varchar2, 20); P_result2.Direction = ParameterDirection.Output; P_result2.CollectionType = OracleCollectionType.PLSQLAssociativeArray; P_result2.Size = myArray2.Count(); P_result2.ArrayBindSize = new int[myArray2.Count()]; cmd.Parameters.Add(P_result2); try { con.Open(); cmd.ExecuteNonQuery(); // 错误触发位置 arrDays = (OracleString[]) cmd.Parameters["UTILDAYS"].Value; con.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); }
Oracle存储过程代码
TYPE myArray2 IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER; CREATE OR REPLACE PROCEDURE GETUTILDAYS ( "DATE1" IN VARCHAR2, "DATE2" IN VARCHAR2, "TESTER" IN VARCHAR2, "UTILDAYS" OUT GETUTIL.myArray2 ) IS currDate VARCHAR2 (20); prevDate VARCHAR2 (20); total NUMBER; total0 NUMBER; cnt NUMBER; firstR NUMBER; CURSOR V_CUR IS SELECT idle_category, TO_CHAR (CAST (probed_time AS DATE), 'MM-DD-YYYY') AS pd FROM inprogress WHERE tester_id = TESTER AND probed_time > TO_TIMESTAMP (CONCAT (DATE1, ' 00:00:00'), 'mm-dd-yyyy hh24:mi:ss') AND probed_time < TO_TIMESTAMP (CONCAT (DATE2, ' 23:59:59'), 'mm-dd-yyyy hh24:mi:ss') ORDER BY probed_time ASC; BEGIN total := 0; total0 := 0; cnt := 1; firstR:=1; FOR V_REC IN V_CUR LOOP currDate := V_REC.pd; IF firstR = 1 THEN firstR:=99; prevDate := V_REC.pd; END IF; IF prevDate = currDate THEN total := total + 1; IF V_REC.idle_category = 0 THEN total0 := total0 + 1; END IF; ELSE UTILDAYS (cnt) := prevDate; cnt := cnt + 1; total := 0; total0 := 0; prevDate := currDate; END IF; END LOOP; UTILDAYS (cnt) := currDate; END GETUTILDAYS;
解决方法
错误核心是C#中定义的输出数组大小不足以容纳存储过程返回的元素数量,或单个元素缓冲区未正确设置。
确保数组Size足够大
NoOfDay的取值需覆盖DATE1到DATE2之间的所有天数,建议直接计算两个日期的天数差再加1,或设置一个足够大的初始值(比如366,覆盖一年所有可能天数),避免实际返回元素数量超过数组大小。
正确初始化ArrayBindSize
ArrayBindSize用于指定数组中每个元素的最大长度,需与存储过程中VARCHAR2(20)的长度匹配。修改代码,将ArrayBindSize的每个元素设置为20:P_result2.ArrayBindSize = Enumerable.Repeat(20, myArray2.Count()).ToArray();- 不设置的话,默认缓冲区大小可能不足,导致单个元素存储报错。
动态匹配数组大小
- 可以在存储过程中添加输出参数返回实际生成的元素数量,或在C#调用前先查询
DATE1到DATE2之间的天数,动态设置数组大小,确保足够容纳所有返回值。
- 可以在存储过程中添加输出参数返回实际生成的元素数量,或在C#调用前先查询
内容的提问来源于stack exchange,提问作者user20774180
相关产品推荐
相关产品推荐

