【发布时间】:2018-07-26 05:27:42
【问题描述】:
我有十几个具有相似结构的不同数据库,每个数据库大约有 50 个不同的表,其中一些表使用顺序 int [Id] 作为主键和标识。
在某些时候,这些数据库被迁移到不同的远程基础设施,即从 Azure 到 AWS,在此过程中的某个地方,Identity 属性丢失了,因此,新的自动插入无法正常工作,因为它无法自动- 增加 Id 并生成有效的主键。
我尝试了多种解决方案,但都在努力让它们中的任何一个工作,因为 SQL-Server 似乎非常挑剔,让您以任何方式弄乱或更改 Identity 列的值,这让我发疯了。
我需要在多个不同的表、多个数据库中重新启用身份,但到目前为止,我发现的解决方案要么非常复杂,要么不切实际,因为这似乎是一个相对简单的问题。
tl;dr - 如何同时为多个不同表中的所有 int 主键启用 Identity?
到目前为止我的方法:
CREATE PROC Fix_Identity @tableName varchar(50)
AS
BEGIN
IF NOT EXISTS(SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(object_id) = @tableName)
BEGIN
DECLARE @keyName varchar(100) = 'PK_dbo.' + @tableName;
DECLARE @reName varchar(100) = @tableName + '.Id_new';
EXEC ('Alter Table ' + @tableName + ' DROP CONSTRAINT ['+ @keyName +']');
EXEC ('Alter Table ' + @tableName + ' ADD Id_new INT IDENTITY(1, 1) PRIMARY KEY');
EXEC ('SET IDENTITY_INSERT [dbo].[' + @tableName + '] ON');
EXEC ('UPDATE ' + @tableName + ' SET [Id_new] = [Id]');
EXEC ('SET IDENTITY_INSERT [dbo].[' + @tableName + '] OFF');
EXEC ('Alter Table ' + @tableName + ' DROP COLUMN Id');
EXEC sp_rename @reName, 'Id', 'Column';
END
END;
我尝试创建这个过程,每个表执行一次,但是我遇到了 UPDATE 语句的问题,我需要保证新值 Identity 列与旧 Id 列具有相同的值,但是这种方法目前不起作用,因为:
无法更新身份列“Id_new”。
【问题讨论】:
-
你用过
set identity_insert off吗? -
我试过了,是的。它仍然不能解决我的问题,因为它需要我删除行并再次添加它们,同时在插入时单独命名每一列。这种方法将非常耗时,因为我正在处理许多表和数据库,除非我遗漏了什么。
-
使用例如为插入语句生成列列表非常容易。
sys.columns. -
身份属性并不像拨动开关那么简单。没有简单的按钮可以让您的 int 列将 identity 属性设置为 true。您将不得不一次处理一张桌子。
-
尝试自动执行此操作很麻烦,尤其是在您有外键的情况下。
标签: sql sql-server