如何获取标识列的 ID?

How to get ID of an identity column?

我在两个 table、UsersProjects 之间建立了多对多关系。

将这两者连接在一起的 table 被命名为 ProjectsUsers

以下是 table 及其关系的描述:

CREATE TABLE "Users"
(
    Email VARCHAR(320) COLLATE SQL_Latin1_General_CP1_CI_AS PRIMARY KEY CHECK(LEN(Email) >= 3),
    --More....
);

CREATE TABLE "Projects"
(
    ProjectID INT PRIMARY KEY IDENTITY,
    --More....
);

CREATE TABLE "ProjectsUsers"
(
    UsersEmail VARCHAR(320) COLLATE SQL_Latin1_General_CP1_CI_AS CHECK(LEN(UsersEmail) >= 3) NOT NULL,
    ProjectsID INT NOT NULL,

    CONSTRAINT ProjectsUsers_PK PRIMARY KEY (UsersEmail, ProjectsID),
    CONSTRAINT ProjectsID_FK FOREIGN KEY (ProjectsID) REFERENCES Projects (ProjectID)  
               ON DELETE CASCADE ON UPDATE CASCADE ,
    CONSTRAINT UsersEmail_FK FOREIGN KEY (UsersEmail) REFERENCES Users(Email) 
               ON DELETE CASCADE ON UPDATE CASCADE
);

我现在正在尝试创建一个存储过程,它将向 Projects table 中插入一个新项目。添加项目后,我想在 ProjectsUsers table 中创建对它的引用。问题是,我无法知道我刚刚创建的项目的 ID - 因此,我无法知道我应该将什么 ID 插入 ProjectsUsers.

所以如果我的存储过程是这样的:

INSERT INTO Projects (Project, CreationDate, ProjectName) 
VALUES (@project,  GETDATE(), @email);

INSERT INTO ProjectsUsers VALUES (@email, ???)

如何获取 ID?

  1. 正如 Sean Lange 提到的,您可以使用 SCOPE_IDENTITY 从您的 proc

  2. 中获取最后插入的 ID
  3. 您还可以使用 OUTPUT 子句并获得可能的许多 ID。您可以在屏幕或 table 中输出,但如果您从具有触发器的 table 中选择,它将无法工作。

像这样使用SCOPE_IDENTITY:

INSERT INTO Projects (Project, CreationDate, ProjectName) 
VALUES (@project, SYSDATETIME(), @email);

DECLARE @ProjectID INT = SCOPE_IDENTITY();

INSERT INTO ProjectsUsers 
VALUES (@email, @ProjectID)

更多 all the relevant details about SCOPE_IDENTITY 在官方 Microsoft 文档网站上。

使用OUTPUT子句!不要使用各种身份函数或变量。这直接解决了你的问题:

DECLARE @ids TABLE (ProjectId int);
INSERT INTO Projects (Project, CreationDate, ProjectName) 
    OUTPUT inserted.ProjectId INTO @ids;
    VALUES (@project,  GETDATE(), @email);

INSERT INTO ProjectsUsers (UsersEmail, ProjectId)
    SELECT @email, ProjectId
    FROM @ids; 

所有其他返回身份的方法都有其特殊性:

  • insert 有多个语句时,它们可能不起作用。
  • 也许并发插入弄乱了值。
  • 也许它们不能很好地与触发器配合使用。