2017-08-17 75 views
0

我有一个非常简单的方法,利用Oracle.ManagedDataAccess来查询Oracle中的数据表。代码如下。Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader缺少结果

private System.Data.DataTable ByQuery(Oracle.ManagedDataAccess.Client.OracleConnection connection, string query) 
{ 
    using(var cmd = new Oracle.ManagedDataAccess.Client.OracleCommand()) 
    { 
     cmd.Connection = connection; 
     cmd.CommandText = query; 
     cmd.CommandType = System.Data.CommandType.Text; 
     var dr = cmd.ExecuteReader(); 
     dr.Read(); 
     var dataTable = new System.Data.DataTable(); 
     dataTable.Load(dr); 
     var recordCount = dataTable.Rows.Count; 
     return dataTable; 
    } 
} 

使用非常简单的查询,例如:

SELECT * FROM NKW.VR_ORDER_LI WHERE CTRL_NO = 10 

返回32行数据。但是,当我使用与我在C#应用程序的连接字符串中使用的完全相同的用户帐户从Oracle SQL Developer运行完全相同的查询时,得到33个结果。

我一直缺少一行数据。

我试着查询不同CTRL_NO:

SELECT * FROM NKW.VR_ORDER_LI WHERE CTRL_NO = 17 

净返回8个结果。 Oracle Sql Developer返回9结果。

我试着删除WHERE语句,只是得到所有结果。

两者之间仍然有1行差异。

我试过Google搜索答案,但一直没有成功。任何帮助或建议,将不胜感激。

更新1:

我确定我总是错过了第一个结果,我在Oracle SQL Developer中看到,当我从我的C#应用​​程序运行完全相同的查询。

UPDATE 2:

如上所述,我将DataTable放在等式之外。

int rowCount = 0; 
while(dr.Read()) 
{ 
    rowCount++; 
} 

rowCount跳过DataTable仍然会导致缺少记录。

UPDATE 3:

测试针对一种完全不同的表,NKW.VR_ORDER_LI实际上是一个视图。由于某种原因,我还是得到了相同的结果,最终我从ExecuteReader()中得到的结果少于从SQL Developer中得到的结果。

+1

我建议你避免使用数据表填充并使用阅读器方法,那样A)你获得更多的性能B)你控制可能在幕后发生的任何解析异常。 – r1verside

+0

我也确定它总是抛出结果的第一行。无论查询在Oracle SQL Developer中显示为第一条记录,这是dataTable.Rows中缺少的记录。 – TGardner

回答

0

我结束了本主题中找出我的问题:

Datareader skips first result

所以在这一切的罪魁祸首就是这部分代码:

var dr = cmd.ExecuteReader(); 
dr.Read(); 
var dataTable = new System.Data.DataTable(); 
dataTable.Load(dr); 

第一dr.Read ()不需要。摆脱这一行代码解决了这个问题。

最终的解决办法:

var dr = cmd.ExecuteReader(); 
var dataTable = new System.Data.DataTable(); 
dataTable.Load(dr); 

我也回到了使用DataTable,因为它是我们如何与交易数据在我们的项目在当前时间互动更加一致。