在SQL Server的表设计中,自增主键是常用的主键生成方式,插入数据时数据库会自动为自增列赋值,很多时候我们需要在插入完成后拿到这个自动生成的ID,用于后续的业务逻辑处理,比如关联插入其他表的记录。SCOPE_IDENTITY函数是SQL Server中专门用于获取当前作用域内最后一次插入操作生成的自增ID的函数,使用它可以在大多数场景下准确拿到我们需要的ID值。

SCOPE_IDENTITY函数的基本介绍
SCOPE_IDENTITY是SQL Server内置的标量函数,它的作用是返回插入到同一作用域中的IDENTITY列内的最后一个IDENTITY值。这里的作用域指的是一个模块,比如存储过程、触发器、函数或者批处理语句,只要是在同一个作用域内执行的插入操作,SCOPE_IDENTITY就能返回对应的自增ID,不会受到其他作用域插入操作的影响。
该函数的语法非常简单,不需要传入任何参数,直接调用即可:
-- 调用SCOPE_IDENTITY函数获取自增ID SELECT SCOPE_IDENTITY() AS LastInsertId;
基础使用示例
我们先创建一个带有自增主键的测试表,然后演示插入数据后使用SCOPE_IDENTITY获取自增ID的过程。
1. 创建测试表
首先创建一个用户表,其中用户ID是自增主键:
-- 创建用户测试表
CREATE TABLE TestUser (
UserId INT IDENTITY(1,1) PRIMARY KEY, -- 自增主键,从1开始每次递增1
UserName NVARCHAR(50) NOT NULL,
CreateTime DATETIME DEFAULT GETDATE()
);
2. 插入数据并获取自增ID
插入一条用户数据,然后立即调用SCOPE_IDENTITY获取刚生成的UserId:
-- 插入用户数据
INSERT INTO TestUser (UserName) VALUES ('张三');
-- 获取刚插入的用户ID
SELECT SCOPE_IDENTITY() AS NewUserId;
执行上述语句后,插入操作会生成一个新的UserId,SCOPE_IDENTITY会返回这个值,比如如果这是第一次插入,返回的结果就是1。
在存储过程中使用SCOPE_IDENTITY
实际开发中我们经常会把插入逻辑封装到存储过程中,这时候使用SCOPE_IDENTITY同样可以正确获取自增ID,因为存储过程本身就是一个独立的作用域。
-- 创建插入用户的存储过程,返回生成的自增ID
CREATE PROCEDURE InsertUser
@UserName NVARCHAR(50),
@NewUserId INT OUTPUT -- 输出参数,返回生成的自增ID
AS
BEGIN
-- 插入用户数据
INSERT INTO TestUser (UserName) VALUES (@UserName);
-- 获取自增ID赋值给输出参数
SET @NewUserId = SCOPE_IDENTITY();
END
GO
-- 调用存储过程测试
DECLARE @UserId INT;
EXEC InsertUser @UserName = '李四', @NewUserId = @UserId OUTPUT;
-- 查看返回的自增ID
SELECT @UserId AS InsertedUserId;
SCOPE_IDENTITY与同类函数的区别
SQL Server中还有两个类似的函数可以获取自增值,分别是@@IDENTITY和IDENT_CURRENT,三者的作用范围有明显区别,使用时需要根据场景选择。
| 函数名称 | 作用范围 | 适用场景 |
|---|---|---|
| SCOPE_IDENTITY | 当前作用域内的最后自增值 | 获取当前语句块、存储过程、触发器中插入的自增ID,最常用 |
| @@IDENTITY | 当前会话所有作用域的最后自增值 | 如果当前会话中有触发器等其他作用域插入了自增数据,会返回触发器的自增值,容易出错 |
| IDENT_CURRENT | 指定表的最后自增值,不限作用域和会话 | 需要获取某张表最后插入的自增ID,不管是不是当前操作插入的场景 |
比如如果插入TestUser表时触发了另一个表的插入操作,那个表也有自增列,这时候@@IDENTITY会返回另一个表的自增ID,而SCOPE_IDENTITY仍然返回TestUser表的自增ID,所以大多数情况下优先使用SCOPE_IDENTITY更稳妥。
应用程序中调用获取自增ID
在C#等应用程序中调用SQL Server插入数据并获取自增ID时,也可以通过执行包含SCOPE_IDENTITY的SQL语句来实现。
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = "Server=.;Database=TestDB;Integrated Security=true";
string insertSql = @"
INSERT INTO TestUser (UserName) VALUES (@UserName);
SELECT SCOPE_IDENTITY() AS NewId;
";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(insertSql, conn))
{
cmd.Parameters.Add(new SqlParameter("@UserName", "王五"));
// 执行查询获取自增ID
object result = cmd.ExecuteScalar();
if (result != null)
{
int newUserId = Convert.ToInt32(result);
Console.WriteLine($"插入的用户ID是:{newUserId}");
}
}
}
}
}
注意事项
- SCOPE_IDENTITY只在插入操作之后立即调用才有效,如果中间执行了其他会生成自增值的插入操作,返回值会变化。
- 如果当前作用域内没有执行过插入自增列的操作,SCOPE_IDENTITY会返回NULL。
- 不要在触发器中使用SCOPE_IDENTITY获取触发器外插入的自增ID,因为触发器是独立的作用域,这时候应该根据需求选择其他函数。
提示:如果插入的表没有自增列,调用SCOPE_IDENTITY会返回NULL,使用前需要确认表结构是否包含IDENTITY属性的列。
SQL_ServerSCOPE_IDENTITY自增ID数据库插入修改时间:2026-07-06 01:06:30