我在 SQL Server 中有一个包含记录包的表。我想将作为主键的 ID 列转换为标识列而不会丢失数据。我想到了以下两种方法:
- 创建具有标识的新表并删除现有表。
- 创建具有标识的新列并删除现有列。
但很明显,它们无法实施,因为保存记录是我的首要任务。
还有另一种方法可以做到这一点吗?
我在 SQL Server 中有一个包含记录包的表。我想将作为主键的 ID 列转换为标识列而不会丢失数据。我想到了以下两种方法:
但很明显,它们无法实施,因为保存记录是我的首要任务。
还有另一种方法可以做到这一点吗?
该解决方案违反了您的第 2 点,但没有其他方法,我认为您的目标是保持旧值,因为没有其他任何意义......
您可以执行以下操作:
可以插入表中的标识列:
set identity_insert YourTable ON
关闭身份插入
set identity_insert YourTable OFF
唯一的问题可能是您的 ID 列已经作为外键连接到其他表。那么您在删除旧列时遇到问题...在这种情况下,您必须在步骤 3 之后删除 ID 列上的外键约束,然后执行步骤 4 到 6,然后重新创建外键约束。
当您使用 SQL Server 2012 时,另一种可能的替代方法是创建一个序列对象,该对象的起始值已在您的表中具有最高 ID +1,然后使用 GET NEXT VALUE FOR 为您的列创建一个默认约束并引用您的您刚刚创建的序列对象。
考虑到源表不是太大:
将新表重命名为旧名称(如果需要,重新建立 FK)
-- Create Sample Existing Table
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
-- Create and Populate New Table (with IDENTITY_INSERT ON)
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
-- Rename Existing Table to Old (can use sp_rename instead, but I can't for temp tables)
SELECT * INTO #tblTestOld FROM #tblTest
DROP TABLE #tblTest
GO
-- Rename New Table to Existing (can use sp_rename instead, but I can't for temp tables)
SELECT * INTO #tblTest FROM #tblTestNew
DROP TABLE #tblTestNew
GO
-- Test Inserting new record
INSERT INTO #tblTest (Val)
VALUES ('d')
-- Verify Results
SELECT * FROM #tblTest
EXEC tempdb.sys.sp_help @objname = N'#tblTest'
-- Drop 'Old' Table (when ready)
DROP TABLE IF EXISTS #tblTestOld
-- Cleanup
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 中选择 *