【问题标题】:SELECT returns DataRow twiceSELECT 两次返回 DataRow
【发布时间】:2016-06-22 13:57:32
【问题描述】:

我刚刚遇到一个针对 SQL Server 2014 运行的查询的奇怪行为。

SELECT * 
FROM ExampleTable 
WHERE ExampleTimestamp < '22.06.2016 15:35:00'

现在奇怪的是它返回一行两次,这是我没想到会发生的。

从数据中我可以看到,重复行的两列在每次出现时都不同(其中之一是ExampleTimestamp 列)。

很可能是数据行被不同的线程更改了,但是数据行然后在一个DataTable中返回两次是否正常?

如果在查询期间更改了一行,如何防止获得两次?

【问题讨论】:

  • 你可以尝试使用DISTINCT
  • 我认为DISTINCT 不会在这里完成这项工作,因为我需要返回所有列。由于两行之间存在差异,它仍然会返回它们。此外,如果我在该列的 PK 上使用 distinct,那么 sql server 应该返回哪个数据部分?
  • 你没有多大意义。它返回 2 行的原因是它们不同,您刚刚说过它们不同。 DISTINCT 也与删除列无关
  • @Rich:是的,它们是不同的,我只是认为SELECT * FROM 的结果将是每个 PK 一行,并且在一个结果中不可能有两次相同的 PK。跨度>
  • 所以您的问题是您的主键中有重复数据?

标签: sql-server sql-server-2014


【解决方案1】:

我可能错了,但根据我的最新知识,对数据行的更新是插入新行并删除旧行。您可能正好在这两者之间进行查询。

当您在事务中包装对数据库的任何写访问时,可以解决此问题。这样,您将获得事务提交之前或之后的状态,但不会在两者之间获得未定义的状态。

我希望这会有所帮助。

撒克逊

【讨论】:

    【解决方案2】:

    您需要正确设置transaction isolation level。例如:

    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    

    请务必小心,因为这些级别会对性能产生重大影响。在同样的情况下,速度比一致性更重要,有时反过来。

    您可能需要在transaction 中运行查询:

    BEGIN TRANSACTION 'tran';  
      SELECT * 
      FROM ExampleTable 
      WHERE ExampleTimestamp < '22.06.2016 15:35:00'  
    COMMIT TRANSACTION 'tran';  
    GO  
    

    更新:REPEATABLE READ 解决了这个问题,READ COMMITTED 没有。

    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    

    根据隔离级别定义,REPEATABLE READ 是防止Non Repeatable Read 现象的least restrictive isolation level

    【讨论】:

    • 我已通过此查询阅读了当前会话的设置:stackoverflow.com/questions/1038113/…。它已经设置为ReadCommitted。至少对于我的 MSSMS 会话,它是这样设置的。由于我没有从我的程序中更改会话,我可以期望设置是相似的吗?
    • 事实上,如果我从那个查询中取出 where 子句,所有会话都设置了 ReadCommitted
    • 我希望如此。请记住,READ COMMITTED 仍然允许重叠线程。它仍然允许重复读取和幻读问题。对于您的情况,您需要防止“不可重复读取”事件。所以REPEATABLE READ 会更适合你。请参阅MSDN docs 或相关的wikipedia page
    • 使用正确的 trx 隔离级别更新了答案。
    • 我的第一个想法是我应该在我的测试环境中更改服务器范围/数据库范围以查看影响,但是正如这篇blogs.msdn.microsoft.com/ialonso/2012/11/26/… 文章告诉我们的那样,没有办法做到这一点。必须为每个打开的会话单独完成。
    【解决方案3】:

    您是说有 1 行符合条件,但结果中有 2 行?

    也许您需要将 TRANSACTION ISOLATION LEVEL 设置为与您所拥有的不同的值。

    https://msdn.microsoft.com/en-GB/library/ms173763.aspx

    【讨论】:

      猜你喜欢
      • 2020-12-04
      • 2014-07-16
      • 2014-01-09
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多