如何在 SQL Server 2012 中关闭标识并插入一行?

Sam*_*tar 1 sql-server

我有下表:

CREATE TABLE [dbo].[Subject] (
    [SubjectId]    INT            IDENTITY (1, 1) NOT NULL,
    [Name]         NVARCHAR (50)  NOT NULL,
    [Version]      ROWVERSION     NOT NULL,
    [CreatedBy]    NVARCHAR (128) NOT NULL,
    [CreatedDate]  DATETIME       NOT NULL,
    [ModifiedBy]   NVARCHAR (128) NOT NULL,
    [ModifiedDate] DATETIME       NOT NULL,
    CONSTRAINT [PK_Subject] PRIMARY KEY CLUSTERED ([SubjectId] ASC)
);
Run Code Online (Sandbox Code Playgroud)

我想创建一个新行,它是 SubjectId 2 行的副本,但我希望新行的 SubjectId 为 0。有没有办法可以关闭身份并将新行作为副本插入SubjectId 为 2 的行。请注意,我不想再次打开身份。

现在按照 Jen 的回答,我有:

SET IDENTITY_INSERT Subject OFF
insert into Subject select 0,Name,version, createdby,createddate,modifiedby,modifiedDate from subject where subjectid=2
Run Code Online (Sandbox Code Playgroud)

这给出了另一个错误:

消息 8101,级别 16,状态 1,第 4 行 表“主题”中标识列的显式值只能在使用列列表且 IDENTITY_INSERT 为 ON 时指定。

M.A*_*Ali 5

SET IDENTITY_INSERT Subject ON 意味着您可以将值显式插入Subject表中的标识列中。

因此,如果您想将值显式插入到标识列中,您将使用TURN ON此功能,并且一旦将值添加到标识列中,您将需要这样做turn it OFF

笔记

此外,当您打开 Identity_Insert 时,您必须在插入语句中明确提及列名。

像这样的东西......

SET IDENTITY_INSERT Subject ON;

INSERT INTO Subject  (subjectid,Name,version, createdby,createddate,modifiedby,modifiedDate)
SELECT 0,Name,version, createdby,createddate,modifiedby,modifiedDate 
FROM subject 
WERE subjectid = 2

SET IDENTITY_INSERT Subject OFF;
Run Code Online (Sandbox Code Playgroud)

还有一件重要的事情。由于您将值显式插入到您的标识列中,不是在这种特殊情况下,而是当您插入一个尚未由 Identity 列生成的值时,稍后当您关闭标识插入并且您希望标识列为以下内容生成值时你,如果你在该列上有一个唯一索引或主键约束,身份列将生成你可能已经显式插入的值,这将导致你的主键列重复(显然 sql server 不会让这种情况发生)并且您会收到类似...“主键列中的重复值”之类的错误。

为避免这种情况,您可以在身份列中显式插入后,通过执行下面显示的操作,重新设置身份列以跳过这些显式插入的值。

DBCC CHECKIDENT(Table_Name, RESEED, 0)   --<-- some smallest value
DBCC CHECKIDENT(Table_Name, RESEED)      --<-- without any seed value
Run Code Online (Sandbox Code Playgroud)

这会将标识列重置为下一个最高可用标识值。

最重要的注意事项

如果它是一个标识值,不管它,不要惹它,让它为你生成值,如果你确实需要影响标识列生成的值,没有标识列,让它成为一个简单的 INT 列.