微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何知道何时停止填充OracleDataAdapter

我正在一个访问oracle的项目中使用OPD.NET dll.

用户可以在文本框中键入任何sql,然后针对db执行.我一直在尝试使用OracleDataAdapter用结果集填充数据表,但我希望能够分阶段返回结果集(对于大型选择查询).

我的问题的一个例子是……

如果一个select查询返回13行数据,下面的代码片段会一直没有问题地执行,直到第四次调用oda.Fill(起始行是15,它不存在),我猜是因为它调用一个读者关闭或类似的东西.

然后它会抛出一个带有消息的system.invalidOperationException – 由于对象的当前状态,Operation无效.

如何确定命令最终将包含多少行(以便我不会遇到异常)?

OracleDataAdapter oda = new OracleDataAdapter(oracleCommand);
oda.Requery = false;

var dts = new DataTable[] { dt };
DataTable dt = new DataTable();

oda.Fill(0,5,dts);
var a = dts[0].Rows.Count;
oda.Fill(a,dts);
var b = dts[0].Rows.Count;
oda.Fill(b,dts);
var c = dts[0].Rows.Count;
oda.Fill(c,dts);
var d = dts[0].Rows.Count;

注意:为简洁起见,我省略了连接和oracle命令对象.

编辑1:
我只是想我可以将用户输入的sql包装在另一个查询中并执行它…
SELECT COUNT(*)FROM(…这里的… intial query …)
但这不是一个干净的解决方案,肯定有一个方法,我还没有看到?

提前致谢.

解决方法

有关Oracle中的分页,请参阅: http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html

如果不运行单独的count(*)查询,则无法知道记录集计数.这是设计的. DataReader和DataAdapter是只进的,只读.

如果效率是一个问题(即,大记录集),则应该让数据库执行分页而不要求OracleDataAdapter运行完整查询.想象一下,如果Google为每个用户搜索填充了一个包含所有1M结果的DataTable !!以下文章解决了这个问题,尽管示例在sql中:

http://www.asp.net/data-access/tutorials/efficiently-paging-through-large-amounts-of-data-cs

修改了下面的示例以允许对任何SQL查询进行分页.调用过程负责跟踪用户当前页面页面大小.如果结果集小于请求的页面大小,则不再有页面.

当然,从用户输入运行自定义sql一个巨大的安全风险.但那不是手头的问题.

祝好运! –Brett

DataTable GetReport(string sql,int pageIndex,int pageSize)
{
    DataTable table = new DataTable();

    int rowStart = pageIndex * pageSize + 1;
    int rowEnd = (pageIndex + 1) * pageSize;

    string qry = string.Format(
@"select * 
from (select rownum ""ROWNUM"",a.*
    from ({0}) a
    where rownum <= :rowEnd)
where ""ROWNUM"" >= :rowStart
",sql);
    try
    {
        using (OracleConnection conn = new OracleConnection(_connStr))
        {
            OracleCommand cmd = new OracleCommand(qry,conn);
            cmd.Parameters.Add(":rowEnd",OracleDbType.Int32).Value = rowEnd;
            cmd.Parameters.Add(":rowStart",OracleDbType.Int32).Value = rowStart;
            cmd.CommandType = CommandType.Text;
            conn.open();
            OracleDataAdapter oda = new OracleDataAdapter(cmd);
            oda.Fill(table);
        }
    }
    catch (Exception)
    {
        throw;
    }
    return table;        
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐