将表的列 ID(主键)更改为自动增量的简单方法

Flá*_*sto 4 sql-server sql-server-2012

我最近开始使用SQL Server,但我仍然不知道做一些事情的最佳方式。

我创建了所有以列 ID 作为主键的表。现在,当我尝试插入值时,出现以下错误:

“无法将值 NULL 插入列 'id'、表 'Project.dbo.Table';列不允许为空值。插入失败。语句已终止。”

这个问题有什么好的、简单的解决方案?

Han*_*non 9

我对非空表的首选方法是使用ALTER TABLE ... SWITCH仅元数据操作的方法。

这是一个简单的测试台设置,由初始表 nameddbo.SwitchTest1和包含一个IDENTITY, named的目标表组成dbo.SwitchTest2

USE tempdb;
IF OBJECT_ID('dbo.SwitchTest1') IS NOT NULL
DROP TABLE dbo.SwitchTest1;
IF OBJECT_ID('dbo.SwitchTest2') IS NOT NULL
DROP TABLE dbo.SwitchTest2;
GO
CREATE TABLE dbo.SwitchTest1
(
    ID INT NOT NULL 
        CONSTRAINT PK_SwitchTest1
        PRIMARY KEY CLUSTERED
    , SomeVal VARCHAR(50) NOT NULL
);
CREATE TABLE dbo.SwitchTest2
(
    ID INT NOT NULL 
        CONSTRAINT PK_SwitchTest2
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
    , SomeVal VARCHAR(50) NOT NULL
);

INSERT INTO dbo.SwitchTest1(ID, SomeVal)
VALUES (1, 'This is a test');
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用ALTER TABLE ... SWITCH方法将dbo.SwitchTest2表中的数据替换为来自 的数据dbo.SwitchTest1,同时保持dbo.SwitchTest2包含IDENTITY列的定义。尽管并非绝对必要,但您可能希望重命名dbo.SwitchTest2after the fact定义中包含的任何约束,以匹配它们过去在dbo.SwitchTest1. 我在下面为主键做了这个。

BEGIN TRANSACTION
BEGIN TRY
    ALTER TABLE dbo.SwitchTest1 SWITCH TO dbo.SwitchTest2;
    DROP TABLE dbo.SwitchTest1;
    EXEC sp_rename @objname = 'dbo.SwitchTest2'
        ,@newname = 'SwitchTest1', @objtype = 'object';
    EXEC sp_rename @objname = 'PK_SwitchTest2'
        , @newname = 'PK_SwitchTest1', @objtype = 'object';
    EXEC sp_recompile @objname = 'dbo.SwitchTest1';
    DBCC CHECKIDENT('dbo.SwitchTest1');
    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION
END CATCH
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我还添加了一个对sp_recompile- 这会导致存储过程、触发器和用户定义的函数在下次运行时重新编译。它通过从过程缓存中删除现有计划来强制在下次运行过程或触发器时创建新计划来实现此目的。这是一件好事™,因为表的 object_iddbo.SwitchTest1已更改。此外,我正在运行DBCC CHECKIDENT('<tablename>');IDENTITY()使用INSERT操作要使用的下一个有效值更新列。

在这里,我们将一个值插入到该SomeVal列中,而没有为该列指定一个值,该ID列现在是一个IDENTITY列:

INSERT INTO dbo.SwitchTest1 (SomeVal)
VALUES ('This is another test');
Run Code Online (Sandbox Code Playgroud)

结果:

SELECT *
FROM dbo.SwitchTest1;
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


ugh*_*hai 6

如果您的表为空,您可以删除并再次重新创建该表,并将其添加IDENTITY(1,1)到 的列定义中id以使您的idProject.dbo.Table自动递增。

像这样的东西。

CREATE TABLE Project.dbo.Table
(
id int IDENTITY(1,1) NOT NULL,
col2 VARCHAR(50) NULL,
...
...
);
Run Code Online (Sandbox Code Playgroud)

您可以PRIMARY KEY像这样添加列名,也可以像这样id int IDENTITY(1,1) NOT NULL PRIMARY KEY,定义所有列后在最后添加CONSTRAINT PK_Table PRIMARY KEY(id)

SQL Server 不允许您IDENTITY通过更改表来添加。使用GObetweenIF EXISTS ...DROP TABLE和 the CREATE TABLEstatements 以单独的批处理运行这些语句。


归档时间:

查看次数:

21031 次

最近记录:

9 年,6 月 前