SQL TRANSACTION 左连接结果为 null

2024-01-13

我遇到一个问题,我在事务中插入用户和地址有 10 秒的延迟,如果在事务执行期间运行我的 select 语句,它将等待事务完成,但我会在连接上得到一个空值。为什么我的选择不等待用户/地址数据都被提交。 如果我在事务完成后运行 select 语句,我将得到正确的结果。为什么我会收到此错误以及使此工作正常进行的通用解决方案是什么

BEGIN TRANSACTION   
 insert into user(dummy) values('text')
 WAITFOR DELAY '00:00:10';
 insert into address(ID_FK) values((SELECT SCOPE_IDENTITY()))
COMMIT TRANSACTION

在事务期间运行导致 join 中为 null

select * from user u left join address a on u.id = a.ID_FK order by id desc
| ID | dummy | ID_FK | 
| 101 | 'text' | null |

交易结果正确后运行

select * from user u left join address a on u.id = a.ID_FK order by id desc
| ID | dummy |  ID_FK|
| 101 | 'text' | 101 |

这种类型的事情在本地 SQL Server 的默认读提交级别下是完全可能的,因为它使用读提交锁定。然后将发生什么取决于执行计划。

下面是一个例子

CREATE TABLE [user]
  (
     id    INT IDENTITY PRIMARY KEY,
     dummy VARCHAR(10)
  );

CREATE TABLE [address]
  (
     ID_FK INT REFERENCES [user](id),
     addr  VARCHAR(30)
  ); 

连接一

BEGIN TRANSACTION

INSERT INTO [user]
            (dummy)
VALUES     ('text')

WAITFOR DELAY '00:00:20';

INSERT INTO address
            (ID_FK,
             addr)
VALUES     (SCOPE_IDENTITY(),
            'Address Line 1')

COMMIT TRANSACTION

连接二(在连接一等待 20 秒时运行此命令)

SELECT *
FROM   [user] u
       LEFT JOIN [address] a
              ON u.id = a.ID_FK
ORDER  BY id DESC
OPTION (MERGE JOIN) 

Returns

id dummy ID_FK addr
1 text NULL NULL

执行计划如下

扫描开启User被连接 1 中已插入行的打开事务阻止。这必须等到事务提交,然后最终才能读取新插入的行。

同时,排序运算符已经请求了行address至此,它消耗了其中的所有行Open方法(即在操作员初始化期间)。这不会被阻止,因为尚未插入任何行address然而。它读取 0 行address这解释了最终结果。

如果您切换到使用读提交快照而不是读提交锁定,您将不会遇到此问题,因为它只会读取语句开头的提交状态,因此不可能出现这种异常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL TRANSACTION 左连接结果为 null 的相关文章

  • 我们可以使用sql列出MS Access数据库中的所有表吗?

    我们可以使用 sql 找到 ms access 中的所有表吗 就像我们在 sql server 中所做的那样 select from sys tables 在sqlite中 SELECT FROM sqlite master where t
  • 将数据表传递到存储过程。有没有更好的办法?

    数据表可以以某种方式传递到 SQL Server 2005 或 2008 中吗 我知道标准方法似乎是将 XML 传递给 SP 并且可以通过某种方式轻松地将数据表转换为 XML 来实现这一点 将 NET 对象传递到 SP 怎么样 那可能吗 我
  • 如何删除MySQL中的所有事件

    如果我想删除某个事件 我需要查询类似的内容 DROP EVENT IF EXISTS eventname 但我找不到一次性删除所有事件的命令 必须一项一项地删除 有没有一次性删除所有事件的SQL DROP EVENT IF EXISTS S
  • INTEGER 到 DATETIME 的转换与 VB6 不同

    我正在查看一些遗留的 VB6 代码 比我的时代早很多年 它对 SQL 2005 数据库运行查询 它提供了日期限制WHERE子句 其中日期作为整数值给出CLng VB6 中的日期 e g WHERE SomeDateField gt 4006
  • 如何在 Postgresql 中将 GIST 或 GIN 索引与 hstore 列一起使用?

    我正在使用 postgresql 9 3 的 hstore 我正在尝试对 hstore 列使用索引就像文档所述 http www postgresql org docs 9 3 static hstore html 我的问题是索引似乎没有被
  • 如何在sql server 2008R2中将单个单元格拆分为多个列?

    我想将每个名称拆分为各个列 create table split test value integer Allnames varchar 40 insert into split test values 1 Vinoth Kumar Raj
  • Postgres 按查询分组

    我正在尝试在 postgres 的查询中使用 group by 我无法让它按照我想要的方式工作 以便根据需要对结果进行分组 这是另一个堆栈问题的扩展我刚刚回答过的递归查询 https stackoverflow com questions
  • 在 Oracle 中如何将多行组合成逗号分隔的列表? [复制]

    这个问题在这里已经有答案了 我有一个简单的查询 select from countries 结果如下 country name Albania Andorra Antigua 我想在一行中返回结果 如下所示 Albania Andorra
  • parent_id 是外键(自引用)并且为 null?

    浏览 Bill Karwin 的书 SQL Antipatterns 第 3 章 Naive Trees 邻接表 父子关系 有一个注释表的示例 CREATE TABLE Comments comment id SERIAL PRIMARY
  • 如何统计订单总价?

    我有这些表 Orders id status user id address id 1 await 1 1 products id name price quantity 1 test1 100 5 2 test2 50 5 order p
  • 如何获取 GROUP_BY 子句中的值列表?

    如果我的表中有这样的数据 id data 1 1 1 2 1 3 2 4 2 5 3 6 3 4 如何在查询 在 sybase 服务器上 中获得这样的结果 id data 1 1 2 3 2 4 5 3 6 4 在mysql中 使用 SEL
  • Mysql UUID_SHORT() 与 UUID() 相当吗

    如果您愿意的话 请快速提出问题或意见 我需要为数据库表生成一些 UUID 自动递增密钥不会减少它 因为我还需要密钥在数据库和系统中保持唯一 UUID 工作正常 但其输出对于行将导出到的某些系统来说太长 UUID SHORT 做得很好 我已经
  • SQL Server 登录错误:用户“NT AUTHORITY\SYSTEM”登录失败

    我创建了一个名为 schoolPool 的应用程序池并将其分配给我的 Web 应用程序 该池的标识已设置为 LocalSystem 当我尝试从应用程序内访问数据库 即打开 SQL 连接 时 我总是收到以下错误 Login failed fo
  • 如何获取存储过程中的表列表?

    数据库中有很多表和sp 我找到特定 sp 存储过程 中使用的表名称 sp depends sp name 没有给出想要的结果 我也用过INFORMATION SCHEMA TABLES INFORMATION SCHEMA ROUTINES
  • SQLite:从命令行仅将模式转储到 .sql 文件中

    我正在尝试转储架构test db仅 即没有数据 到名为的文件中schema sql从 OS X 中的命令行 无需启动 sqlite3 我知道我能做到 sqlite3 open test db output schema sql schema
  • 内连接中的排序依据

    我将内部连接放入查询中 我得到了结果 但不知道数据如何输入输出 任何人都可以告诉我内部连接如何匹配数据 下面我显示了一个图像 有两张桌子 一张或两张桌子 根据我的说法 第一行应该是 Mohit 但输出不同 请告诉我 In SQL 输出的顺序
  • 查询以查找平均加权价格

    我在 Oracle 中有一个表 每个给定部分包含多行 每行都有一个与其关联的数量和价格 还有一个给定零件的行集相加的总数量 以下是数据示例 我需要的是获得该零件的平均加权价格 例如 如果数量为 100 的零件的价格为 1 数量为 50 的零
  • SQL:计算高于组平均值的值

    如何使用 SQL 计算高于一组平均值的值 例如 我有桌子A with q t 1 5 1 6 1 2 1 8 2 6 2 4 2 3 2 1 第 1 组的平均值为 5 25 组内有两个值高于5 25 8和6 因此高于该组平均值的值的数量为
  • 用户表到用户和用户首选项。这是正常化了吗?

    我有一张桌子叫Users其偏好列表不断增加 这些首选项可以包括 ReligionId 它将连接到另一个包含宗教列表的表 偏好列表正在不断增加 我想把它分开Users表分成2个表 我认为行之有效的策略是制作一个单独的表 名为UserPrefe
  • Linq 查询可以从 Sql 数据库检索 BLOB 吗?

    Linq 查询可以从 Sql 数据库检索 BLOB 吗 他们是怎么出来的 LINQ To SQL 类为 SQL Server 中的所有二进制和 varbinary 字段创建 System Data Linq Binary 类型的属性 Bin

随机推荐