SQLServer获取插入记录的主键值的四种方式与测试比较
2021/8/20 19:07:09
本文主要是介绍SQLServer获取插入记录的主键值的四种方式与测试比较,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
概念释义
会话(Session):当客户端应用程序连接到SQL Server时,双方建立一个“会话”来交换信息。严格地说,会话与底层物理连接不同,它是连接的SQL Server逻辑表示。比如说,在 SQL Server Management Studio 新建一个查询、打开了一个对话框,即表示新建了一个”会话“;在代码中使用 SqlConnection,new了一个连接,即表示新建了一个”会话“。
作用域(Scope): 是一个模块:存储过程、触发器、函数或批处理。因此,如果两条语句位于相同的存储过程、函数或批处理中,则它们处于相同的作用域。
一、所有方式
方法 | 描述 | 作用域 | 会话 |
---|---|---|---|
SCOPE_IDENTITY() | 返回在当前活动连接中的任何表的最后的ID | 同一作用域 | 同一会话 |
@@IDENTITY | 返回在当前活动连接中的任何表的最后的ID | 任何作用域 | 同一会话 |
IDENT_CURRENT(table_name) | 返回指定表的最后的ID | 任何作用域 | 任何会话 |
OUTPUT 子句 | 返回插入数据的任何指定的列信息(触发器必须禁用) | / | / |
二、使用示例
2.1 应用场景
有表 Tb1 及其两个 Insert 触发器(为了模拟“作用域”):Tr1、Tr1_2
有表 Tb2 及其一个 Insert 触发器(为了模拟“作用域”):Tr2
- Tb1
CREATE TABLE [dbo].[Tb1]( [ID] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](8) NULL, CONSTRAINT [PK_Tb1] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
- Tr1:当 Tb1插入一条数据时,再向 Tb1 插入一条数据
CREATE TRIGGER [dbo].[Tr1] ON [dbo].[Tb1] AFTER INSERT AS BEGIN declare @name sysname select @name=Name from inserted insert into dbo.Tb1(Name) values(@name+'byTr1'); END
- Tr1_2:当 Tb1 插入一条数据时,向 Tb2 插入一条数据
CREATE TRIGGER [dbo].[Tr1_2] ON [dbo].[Tb1] AFTER INSERT AS BEGIN declare @name sysname select @name=Name from inserted insert into dbo.Tb2(Name) values(@name+'_byTr1_2'); END
- Tb2
CREATE TABLE [dbo].[Tb2]( [ID] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](8) NOT NULL, CONSTRAINT [PK_Tb2] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
- Tr2
CREATE TRIGGER [dbo].[Tr2] ON [dbo].[Tb2] AFTER INSERT AS BEGIN declare @name sysname select @name=Name from inserted insert into dbo.Tb2(Name) values(@name+'_byTr2'); END
2.2 测试方式
注:Tb1 的触发器及代表了“作用域”,已包括在如下个测试过程中
- 执行向 Tb1 插入一条数据,在同一会话中,分别使用三种方式(除output)获取插入记录的 ID
insert into dbo.Tb1(Name) values('User1') select SCOPE_IDENTITY() as [SCOPE_IDENTITY] select @@IDENTITY as [@@IDENTITY] select IDENT_CURRENT('dbo.Tb1') as [IDENT_CURRENT('dbo.Tb1')] select IDENT_CURRENT('dbo.Tb2') as [IDENT_CURRENT('dbo.Tb2')] select ID as [Tb1.ID], Name as [Tb1.Name] from dbo.Tb1 select ID as [Tb2.ID], Name as [Tb2.Name] from dbo.Tb2 /* truncate table dbo.Tb1 truncate table dbo.Tb2 */
输出:
- 执行向 Tb1 插入一条数据,在两个不同会话中,分别使用三种方式(除output)获取插入记录的 ID
(使用程序模拟并发易实现)
- 关闭 Tb1 触发器,执行向 Tb1、Tb2 分别插入一条数据,在同一会话中,分别使用四种方式获取插入记录的 ID
insert into dbo.Tb1(Name) output inserted.ID as [Tb1.output inserted.ID] values('User1') insert into dbo.Tb2(Name) values('User2') select SCOPE_IDENTITY() as [SCOPE_IDENTITY()] select @@IDENTITY as [@@IDENTITY] select IDENT_CURRENT('dbo.Tb1') as [IDENT_CURRENT('dbo.Tb1')] select IDENT_CURRENT('dbo.Tb2') as [IDENT_CURRENT('dbo.Tb2')] select ID as [Tb1.ID], Name as [Tb1.Name] from dbo.Tb1 select ID as [Tb2.ID], Name as [Tb2.Name] from dbo.Tb2 /* truncate table dbo.Tb1 truncate table dbo.Tb2 */
输出:
- 关闭 Tb1 触发器,执行向 Tb1、Tb2 分别插入一条数据,在两个不同会话中,分别使用 四种方式获取插入记录的 ID
(使用程序模拟并发易实现)
三、结论
若获取当前首次插入的记录ID,推荐使用 SCOPE_IDENTITY()
这篇关于SQLServer获取插入记录的主键值的四种方式与测试比较的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-01-08Docker下的SqlServer发布订阅启用
- 2023-06-05Docker安装MS SQL Server并使用Navicat远程连接
- 2023-05-25深入浅出 SQL Server CDC 数据同步
- 2023-05-12通过空间占用和执行计划了解SQL Server的行存储索引
- 2023-04-24以SQLserver为例的Dapper详细讲解
- 2022-11-30SQL server高级函数查询
- 2022-11-26SQL SERVER数据库服务器CPU不能全部利用原因分析
- 2022-11-21SQL Server 时间算差值/常用函数
- 2022-11-20调试Archery连接SQL Server提示驱动错误
- 2022-10-22SQL Server 完整、差异备份+完整、差异还原(详细讲解,规避错误)