如何获取标识列的 ID?
How to get ID of an identity column?
我在两个 table、Users
和 Projects
之间建立了多对多关系。
将这两者连接在一起的 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?
正如 Sean Lange 提到的,您可以使用 SCOPE_IDENTITY 从您的 proc
中获取最后插入的 ID
您还可以使用 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
有多个语句时,它们可能不起作用。
- 也许并发插入弄乱了值。
- 也许它们不能很好地与触发器配合使用。
我在两个 table、Users
和 Projects
之间建立了多对多关系。
将这两者连接在一起的 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?
正如 Sean Lange 提到的,您可以使用 SCOPE_IDENTITY 从您的 proc
中获取最后插入的 ID
您还可以使用 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
有多个语句时,它们可能不起作用。 - 也许并发插入弄乱了值。
- 也许它们不能很好地与触发器配合使用。