Reader 返回 5 行,数据表有 1

Posted

技术标签:

【中文标题】Reader 返回 5 行,数据表有 1【英文标题】:Reader returning 5 rows, data table has 1 【发布时间】:2012-02-28 19:17:06 【问题描述】:

我有一个 sql 语句,我正试图对一个 sqlite 数据库执行。

问题是,只有这一条 sql 语句,数据表报告 1 行事件,但如果我查看阅读器,结果视图中有 5 行。

SQL:

SELECT 
    f.host_id,h.hostname,h.computer_name_dns_fully_qualified,
    l.username,l.logon_domain 
FROM scans s 
LEFT JOIN hosts h ON h.scan_id=s.scan_id 
LEFT JOIN logged_on_users l ON l.host_id=h.host_id 
LEFT JOIN hosts f ON f.computer_name_netbios LIKE l.logon_ser...

它是这样称呼的:

        var dt = new DataTable();

        try
        
            var com = new SQLiteCommand(_con)  CommandText = sql ;
            var reader = com.ExecuteReader();
            dt.Load(reader);
            reader.Close();
        
        catch
        
        

        return dt;

【问题讨论】:

所以当你使用 SQL 客户端并直接运行这条 SQL 语句时,你会得到 1 行,但通过代码阅读器有 5 行?它们是相同的 5 行吗? 不。当我在 SQL 浏览器中运行它时,它返回 5。 reader.resultsview 有 5 个对象。 dt.load(读者);现在 dt 包含 1 行。 为了完整起见,您可以添加实例化 dt 的位置吗? 如果您在表 scans 中有 1 行,则加入具有相同 scan_id 的更多行的其他表将为您提供所有连接的行......如果是这种情况,它是正确且符合预期的结果 问题是,尽管它肯定返回 5 行,但返回的行的主键是相同的。尽管数据不同。我意识到无论如何我实际上需要不同的主键。如果您遇到此问题,请检查您是否没有获得包含所有相同数据的一列。此外,有人提出了一个 ORDER BY,他们声称可以解决同样的问题,尽管我无法让它工作。 SELECT f.host_id as host_id,h.hostname as ... 应该是:(注意只有第 8 个字符发生了变化) SELECT h.host_id as host_id,h.hostname as ... 【参考方案1】:

问题是MSDN文章中描述的数据表填充方法是匹配主键并覆盖每一行。 我知道如果这是真的,只会返回最后一行。我回去撤消了所有代码更改,果然,只返回了最后一行。这是因为加载到数据表中的每一行都覆盖了之前的行。 如果你有这个问题,而且我现在已经被指出了一些线程——有些问题长达 4 年没有解决——停止、删除并检查一个特定列中的所有值是否相同; Datatables 可能会按该列键入您的数据。

【讨论】:

【参考方案2】:

在查询中添加 order by。 DataTables 需要一个唯一的字段来处理和排序。因为数据表可以通过将阅读器加载到其中来更新内容。

见:Similar Issue

【讨论】:

我将对您的评论投赞成票,但发布我自己的解决方案,希望人们能理解这个问题。问题是所有行都返回相同的主键。【参考方案3】:

避免使用空的 catch-block,因为它会导致这样的问题。而是记录异常和/或抛出异常。 http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET

Load 方法使用加载的IDataReader 中的第一个结果集,并在成功完成后,将读者的位置设置为下一个结果集,如果任何。

显然有一个例外,因此您只能在 DataTable 中看到一行。所以你应该设置一个断点来看看会发生什么。

当出现属于finally-block(或使用using 语句)的异常时,您也不会关闭连接。

【讨论】:

是的,但它会说 x 行数。除了这个之外,每个请求都会发生这种情况。 什么会说x行数?显然有一个例外,所以你应该设置一个断点来看看会发生什么。当存在属于 finnally-block 的异常时,您也不会关闭连接(或使用 using 语句)。 dt.rows.count 会显示 1。其他查询会显示 24、1061、40 等。 catch(Exception e) Console.WriteLine(e.Message); 控制台上仍然没有打印消息【参考方案4】:

您的加入扫描到主机和主机到logged_on_users 然后过滤logged_on_users 如果带有过滤器的表产生多行,那么您将获得笛卡尔乘法。

尝试将部分查询分解为子查询。

如果这是 SQL Server,请向业务工作室询问查询计划 - 将其发布为图片,我们可以清楚地回答。

谢谢 西蒙

【讨论】:

不。不是笛卡尔连接问题。如果是 SQL 语句的问题,我不会在阅读器和 SQL 客户端中得到 5 行。 如果我正确理解 Bluebaron 的评论,问题是变量 dt 中有 1 行而不是 SQL 返回的 5 行 对。 SQL 返回 5 行。 dt.load 无法正常工作。 对不起,我误解了,感谢 deathApril 的问题,o 和 Bluebaron 的直接回答:-)

以上是关于Reader 返回 5 行,数据表有 1的主要内容,如果未能解决你的问题,请参考以下文章

00091_字符输入流Reader

字符流Reader和Writer

地理空间云怎么找矢量图

如果我使用itertool中的islice从第5行开始,如何使用DictReader?

数据可视化:CSV格式,JSON格式

无法从 Reader 读取数据