我在SQL Server中有一张包含很多记录的表格。我想将主键列ID转换为自增列,但不希望丢失数据。我考虑了以下两种方法:
- 新建一个带有自增列的表格,并删除原始表格。
- 新建一个带有自增列的列,并删除原始列。
但显然它们都不能被实施,因为保留记录是我的首要任务。
是否还有其他方法可以做到这一点?
我在SQL Server中有一张包含很多记录的表格。我想将主键列ID转换为自增列,但不希望丢失数据。我考虑了以下两种方法:
但显然它们都不能被实施,因为保留记录是我的首要任务。
是否还有其他方法可以做到这一点?
make it possible to insert into identity columns in your table:
set identity_insert YourTable ON
turn identity insert off
set identity_insert YourTable OFF
唯一的问题可能是您已将ID列连接为其他表的外键。然后,您在删除旧列时会遇到问题... 在这种情况下,在第3步之后必须删除ID列上的外键约束,然后执行第4至6步,最后重新创建外键约束。
如果您正在使用SQL Server 2012,另一种可能的选择是创建一个序列对象,该对象具有表中最高ID +1的起始值,然后使用GET NEXT VALUE FOR为列创建默认约束,并引用您刚刚创建的序列对象。
考虑源表不太大的情况:
将新表重命名为旧名称(如果需要,重新建立FK)
-- 创建示例现有表
DROP TABLE IF EXISTS #tblTest
CREATE TABLE #tblTest
(
ID INT NOT NULL
, Val VARCHAR(10) NOT NULL
)
INSERT INTO #tblTest
(
ID
, Val
)
VALUES
(1, 'a')
, (2, 'b')
, (4, 'c')
GO
-- 创建并填充新表(打开IDENTITY_INSERT)
DROP TABLE IF EXISTS #tblTestNew
CREATE TABLE #tblTestNew
(
ID INT IDENTITY(1, 1) NOT NULL
, Val VARCHAR(10) NOT NULL
)
SET IDENTITY_INSERT #tblTestNew ON
INSERT INTO #tblTestNew
(
ID
, Val
)
(
SELECT
#tblTest.ID
, #tblTest.Val
FROM
#tblTest
)
SET IDENTITY_INSERT #tblTestNew OFF
GO
-- 将现有表重命名为旧表(可以使用sp_rename,但我不能用于临时表)
SELECT * INTO #tblTestOld FROM #tblTest
DROP TABLE #tblTest
GO
-- 将新表重命名为现有表(可以使用sp_rename,但我不能用于临时表)
SELECT * INTO #tblTest FROM #tblTestNew
DROP TABLE #tblTestNew
GO
-- 测试插入新记录
INSERT INTO #tblTest (Val)
VALUES ('d')
-- 验证结果
SELECT * FROM #tblTest
EXEC tempdb.sys.sp_help @objname = N'#tblTest'
-- 删除“旧”表(准备好后)
DROP TABLE IF EXISTS #tblTestOld
-- 清理
DROP TABLE IF EXISTS #tblTest
DROP TABLE IF EXISTS #tblTestNew
DROP TABLE IF EXISTS #tblTestOld
如果表格非常大,请考虑日志增长、恢复模型、可能的单用户模式等。
create table t1 (col1 int, col2 varchar(10))
insert into t1 values (10, 'olddata')
--添加身份列
alter table t1 add col3 int identity(1,1)
GO
--重命名或删除旧列
alter table t1 drop column col1
--将新列重命名为旧列名称
exec sp_rename 't1.col3', 'col1', 'column'
GO
--添加新的测试,审核表格
insert into t1 values ( 'newdata')
选择 * 从 t1