ILSPY找出了出问题的那一段源码,但是,看不出哪里有原因,datarow明明次第五个元素时先有判断的。大招唤术——牛人们来帮我看看吧,找出具体是哪句代码出了问题,因为这个方式是没有参数的,而且是查询操作,而且查询语句是没有问题的(不然就报oracle错误了)。
而且,【索引超出了数组界限】这种情况出现在查询操作中,真心让我无语啊,所有数据都来源于数据库,假如期间数组大小出了问题,我想应该就是这一段代码的问题了。
1 // Oracle.ManagedDataAccess.Client.OracleDataReader 2 internal DataTable GetMinSchemaTable() 3 { 4 if (ProviderConfig.m_bTraceLevelPrivate) 5 { 6 Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, new string[0]); 7 } 8 DataTable result; 9 try 10 { 11 if (this.m_readerImpl == null || this.m_readerImpl.m_sqlMetaData == null) 12 { 13 result = null; 14 } 15 else 16 { 17 DataTable dataTable = null; 18 if (this.m_sqlStatementType != SqlStatementType.SELECT) 19 { 20 if (this.m_refCursor != null) 21 { 22 RefCursorInfo refCursorInfo = this.m_refCursor.m_refCursorInfo; 23 if (refCursorInfo != null && refCursorInfo.columnInfo.Rows.Count > 0) 24 { 25 dataTable = refCursorInfo.columnInfo; 26 } 27 } 28 else 29 { 30 ConfigBaseClass.StoredProcedureInfo storedProcInfo = ConfigBaseClass.GetInstance(true).GetStoredProcInfo(this.m_storedProcName); 31 if (storedProcInfo != null) 32 { 33 dataTable = storedProcInfo.GetColumnInfo(this.m_readerImpl.m_currentRefCursorIndex); 34 } 35 } 36 } 37 DataTable dataTable2 = new DataTable("MinSchemaTable"); 38 this.PopulateMetaData(false); 39 dataTable2.MinimumCapacity = this.m_fieldCount; 40 if (this.m_sqlStatementType != SqlStatementType.SELECT) 41 { 42 dataTable2.ExtendedProperties["REFCursorName"] = ((this.m_readerImpl.m_currentRefCursorIndex == 0) ? "REFCursor" : ("REFCursor" + this.m_readerImpl.m_currentRefCursorIndex)); 43 } 44 dataTable2.Columns.Add("ColumnName", typeof(string)); 45 dataTable2.Columns.Add("BaseColumnName", typeof(string)); 46 dataTable2.Columns.Add("BaseTableName", typeof(string)); 47 dataTable2.Columns.Add("OraDbType", typeof(OracleDbType)); 48 dataTable2.Columns.Add("BaseSchemaName", typeof(string)); 49 ColumnLocalParsePrimaryKeyInfo columnLocalParsePrimaryKeyInfo = ColumnLocalParsePrimaryKeyInfo.Null; 50 bool flag = this.m_readerImpl.m_sqlMetaData.m_sqlMetaInfo != null && this.m_readerImpl.m_sqlMetaData.m_sqlMetaInfo.m_columnMetaInfo != null; 51 for (int i = 0; i < this.m_fieldCount; i++) 52 { 53 DataRow dataRow = dataTable2.NewRow(); 54 ColumnDescribeInfo columnDescribeInfo = this.m_readerImpl.m_sqlMetaData.m_columnDescribeInfo[i]; 55 if (flag) 56 { 57 columnLocalParsePrimaryKeyInfo = this.m_readerImpl.m_sqlMetaData.m_sqlMetaInfo.m_columnMetaInfo[i]; 58 } 59 dataRow[0] = columnDescribeInfo.pColAlias; 60 dataRow[1] = columnLocalParsePrimaryKeyInfo.m_columnName; 61 dataRow[2] = columnLocalParsePrimaryKeyInfo.pTabName; 62 dataRow[3] = this.GetOraDbType(i); 63 dataRow[4] = columnLocalParsePrimaryKeyInfo.m_schemaName; 64 if (this.m_sqlStatementType != SqlStatementType.SELECT && dataTable != null) 65 { 66 object obj = dataTable.Rows[i]["ColumnName"]; 67 if (obj != null && obj != DBNull.Value) 68 { 69 dataRow[0] = (string)obj; 70 } 71 object obj2 = dataTable.Rows[i]["BaseColumnName"]; 72 if (obj2 != null && obj2 != DBNull.Value) 73 { 74 dataRow[1] = (string)obj2; 75 } 76 object obj3 = dataTable.Rows[i]["BaseTableName"]; 77 if (obj3 != null && obj3 != DBNull.Value) 78 { 79 dataRow[2] = (string)obj3; 80 } 81 object obj4 = dataTable.Rows[i]["ProviderType"]; 82 if (obj4 != null && obj4 != DBNull.Value) 83 { 84 dataRow[3] = (OracleDbType)obj4; 85 } 86 object obj5 = dataTable.Rows[i]["BaseSchemaName"]; 87 if (obj5 != null && obj5 != DBNull.Value) 88 { 89 dataRow[4] = (string)obj5; 90 } 91 object obj6 = dataTable.Rows[i]["UdtTypeName"]; 92 if (obj6 != null && obj6 != DBNull.Value) 93 { 94 dataRow[5] = obj6; 95 } 96 } 97 dataTable2.Rows.Add(dataRow); 98 } 99 dataTable2.AcceptChanges(); 100 result = dataTable2; 101 } 102 } 103 catch (Exception ex) 104 { 105 OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, ex, null); 106 throw; 107 } 108 finally 109 { 110 if (ProviderConfig.m_bTraceLevelPrivate) 111 { 112 Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, new string[0]); 113 } 114 } 115 return result; 116 }
来看看所抛出的异常:
1 索引超出了数组界限。 2 在 Oracle.ManagedDataAccess.Client.OracleDataReader.GetMinSchemaTable() 3 在 Oracle.ManagedDataAccess.Client.OracleDataReader.set_IsFillReader(Boolean value) 4 在 Oracle.ManagedDataAccess.Client.OracleDataAdapter.Fill(DataSet dataSet, String srcTable, IDataReader dataReader, Int32 startRecord, Int32 maxRecords) 5 在 Oracle.ManagedDataAccess.Client.OracleDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) 6 在 System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable) 7 在 EdiSharp.Utility.Data.OracleManagedDbHelperBase.GetDataTable(String sql) 8 在 Cot_DataFactory.OracleDAL.OracleDBHelper.GetDataTable(String SQLString) 9 在 Cot_DataFactory.BLL.B_CtnDymanic.ChangeLYGTZW(String wt_no, String ctn, Int32 state, String strIODate) 10 在 Cot_DataFactory.BLL.B_CtnDymanic.FullCtnOut(String wt_no, String ctn, String ctn_type, String ctn_corp, String strIODate) 11 在 Cot_DataFactory.Handles.Sync_Empty_Ctn.Work()
显然不是Oracle数据库抛出的,而是这最后一个方法抛出的,就是那个
Oracle.ManagedDataAccess.Client.OracleDataReader.GetMinSchemaTable()方法,这个方法的源码就是上面的那段。
遇到同样的问题...请问解决了吗?
官方没有给出明确的解决办法,根据反编译的结果是ODA缓存了查询结果的结构,一旦结构变化 ,将受到影响。解决的办法就是不缓存结构(或者修改源码使得出错时重新获取新的结构,但是,我没这样去操作)。不缓存结构要在连接串里面指定:Metadata Pooling=false 以关闭结构缓存池。但是,这样肯定会导致查询性能下降,不过,目前我们也是这样使用的。