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的主要内容,如果未能解决你的问题,请参考以下文章