Adding an identity to an existing column
我需要将表的主键更改为标识列,并且表中已有许多行。
我有一个脚本来清理ID以确保它们从1开始顺序启动,在我的测试数据库上运行正常。
什么是将命令改为具有标识属性的SQL命令?
您无法更改现有列的标识。
你有2个选择,
使用标识创建一个新表并删除现有表
使用标识创建新列并删除现有列
方法1.(新表)您可以在此处保留新创建的标识列上的现有数据值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | CREATE TABLE dbo.Tmp_Names ( Id INT NOT NULL IDENTITY(1, 1), Name VARCHAR(50) NULL ) ON [PRIMARY] GO SET IDENTITY_INSERT dbo.Tmp_Names ON GO IF EXISTS ( SELECT * FROM dbo.Names ) INSERT INTO dbo.Tmp_Names ( Id, Name ) SELECT Id, Name FROM dbo.Names TABLOCKX GO SET IDENTITY_INSERT dbo.Tmp_Names OFF GO DROP TABLE dbo.Names GO EXEC sp_rename 'Tmp_Names', 'Names' |
方法2(新列)您无法在新创建的标识列上保留现有数据值,标识列将保留数字序列。
1 2 3 4 5 6 7 8 | ALTER TABLE Names ADD Id_new INT IDENTITY(1, 1) GO ALTER TABLE Names DROP COLUMN ID GO EXEC sp_rename 'Names.Id_new', 'ID', 'Column' |
有关更多详细信息,请参阅以下Microsoft SQL Server论坛帖子:
如何将列更改为标识(1,1)
在SQL 2005及更高版本中,可以在不更改表的数据页的情况下解决此问题。这对于触摸每个数据页可能需要几分钟或几小时的大型表非常重要。即使标识列是主键,是集群或非集群索引的一部分,或者其他陷阱可以使更简单的"添加/删除/重命名列"解决方案绊倒,这个技巧也有效。
下面是技巧:您可以使用SQL Server的ALTER TABLE ... SWITCH语句来更改表的模式而不更改数据,这意味着您可以使用具有相同表模式但没有IDENTITY列的IDENTITY替换表。同样的技巧可以将IDENTITY添加到现有列。
通常,ALTER TABLE ... SWITCH用于有效地用新的空分区替换分区表中的完整分区。但它也可以用在非分区表中。
我用这个技巧在5秒内将IDENTITY中25亿行表中的一列转换为非IDENTITY(为了运行一个多小时查询,其查询计划更适合非IDENTITY列),然后在不到5秒的时间内恢复IDENTITY设置。
这是一个如何工作的代码示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | CREATE TABLE Test ( id INT IDENTITY(1,1), somecolumn VARCHAR(10) ); INSERT INTO Test VALUES ('Hello'); INSERT INTO Test VALUES ('World'); -- copy the table. use same schema, but no identity CREATE TABLE Test2 ( id INT NOT NULL, somecolumn VARCHAR(10) ); ALTER TABLE Test SWITCH TO Test2; -- drop the original (now empty) table DROP TABLE Test; -- rename new table to old table's name EXEC sp_rename 'Test2','Test'; -- update the identity seed DBCC CHECKIDENT('Test'); -- see same records SELECT * FROM Test; |
这显然比其他答案中的解决方案更复杂,但如果你的桌子很大,这可以真正节省生命。有一些警告:
- 据我所知,使用此方法,您可以使用此方法更改有关表格列的唯一信息。不允许添加/删除列,更改可为空性等。
- 在进行切换之前,您需要删除foriegn密钥并在之后恢复它们。
- 对于WITH SCHEMABINDING函数,视图等也是如此
- 新表的索引需要完全匹配(相同的列,相同的顺序等)
- 旧表和新表需要位于同一文件组中。
- 仅适用于SQL Server 2005或更高版本
- 我以前认为这个技巧只适用于SQL Server的企业版或开发者版(因为分区仅在Enterprise和Developer版本中支持),但Mason G. Zhwiti在下面的评论中说它也适用于SQL标准版。我认为这意味着对Enterprise或Developer的限制不适用于ALTER TABLE ... SWITCH。
TechNet上有一篇很好的文章详细说明了上述要求。
更新 - Eric Wu在下面发表评论,增加了有关此解决方案的重要信息。在此处复制以确保它得到更多关注:
There's another caveat here that is worth mentioning. Althought the
new table will happily receive data from the old table, and all the
new rows will be inserted following a identity pattern, they will
start at 1 and potentially break if the said column is a primary key.
Consider runningDBCC CHECKIDENT(' immediately after')
switching. See msdn.microsoft.com/en-us/library/ms176057.aspx for more
info.
如果使用新行主动扩展表(意味着在添加IDENTITY和添加新行之间没有太多停机时间,那么您需要在新表中手动设置标识种子值,而不是
显然,如果没有新的行添加到表中(或者它们只是偶尔添加,就像每日ETL过程一样),那么这种竞争条件就不会发生,所以
您不能将列更改为IDENTITY列。您需要做的是创建一个新列,该列从一开始就定义为IDENTITY,然后删除旧列,并将新列重命名为旧名称。
1 2 3 4 5 | ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1) ALTER TABLE (yourTable) DROP COLUMN OldColumnName EXEC sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN' |
渣
这里描述了很酷的解决方案:
SQL SERVER - 在列上添加或删除标识属性
简而言之,在SQL Manager中手动编辑表,切换标识,不保存更改,只显示将为更改创建的脚本,复制并稍后使用。
它节省了大量时间,因为它(脚本)包含与您更改的表相关的所有外键,索引等。手动写这个......上帝保佑。
考虑使用SEQUENCE而不是IDENTITY。
在SQL Server 2014(我不知道更低版本)你可以使用序列简单地做到这一点。
1 2 3 | CREATE SEQUENCE sequence_name START WITH here_higher_number_than_max_existed_value_in_column INCREMENT BY 1; ALTER TABLE TABLE_NAME ADD CONSTRAINT constraint_name DEFAULT NEXT VALUE FOR sequence_name FOR column_name |
从此处:序列作为列的默认值
简单的解释
使用sp_RENAME重命名现有列
EXEC sp_RENAME'Table_Name.Existing_ColumnName','New_ColumnName','COLUMN'
重命名示例:
现有列UserID重命名为OldUserID
1 | EXEC sp_RENAME 'AdminUsers.UserID' , 'OldUserID', 'COLUMN' |
然后使用alter query添加新列以设置为主键和标识值
1 | ALTER TABLE TableName ADD Old_ColumnName INT NOT NULL PRIMARY KEY IDENTITY(1,1) |
设置主键的示例
新创建的列名称是UserID
1 | ALTER TABLE Users ADD UserID INT NOT NULL PRIMARY KEY IDENTITY(1,1) |
然后删除重命名列
1 | ALTER TABLE TABLE_NAME DROP COLUMN Renamed_ColumnName |
Drop重命名列的示例
1 | ALTER TABLE Users DROP COLUMN OldUserID |
现在我们将主键和标识添加到表中的现有列。
我是一名java开发人员,碰巧遇到没有DBA的团队,而且作为开发人员,我无法获得DBA权利。我的任务是在两个数据库之间移动整个模式,所以没有DBA,我必须通过运行脚本来完成它,而不能在SQL Server 2008中使用GUI,因为我没有管理员权限。
一切都没有问题,但是,当在新的schema.table上运行存储过程时,我发现我丢失了表中的标识字段。我仔细检查了创建表的脚本,但是,当我运行脚本时,SQL Server没有得到它。后来我被DBA告知他之前见过同样的问题。
无论如何,对于SQL Server 2008,这些是我为解决这个问题而采取的步骤,所以我在这里发布了这个,希望它能帮到某个人。这就是我所做的,因为我在另一个表上有FK依赖,这使得这更难:
我使用此查询来验证确实缺少身份并查看表上的依赖项。
1.)查找表格的统计数据:
1 | EXEC sp_help 'dbo.table_name_old'; |
2.)创建一个重复的,相同的新表,除了在PK字段上添加标识字段之前的位置。
3.)禁用身份以移动数据。
1 | SET IDENTITY_INSERT dbo.table_name ON |
4.)传输数据。
1 2 3 4 5 6 7 8 | INSERT INTO dbo.table_name_new ( field1, field2, etc... ) SELECT field1, field2, etc... FROM dbo.table_name_old; |
5.)验证数据是否存在。
1 | SELECT * FROM dbo.table_name_new |
6.)重新启用身份。
1 | SET IDENTITY_INSERT ToyRecP.ToyAwards.lkpFile_New OFF |
7.)这是我发现的最好的脚本,它可以获得所有FK关系,以验证原始表引用哪些表作为依赖项
我遇到了很多,所以它是守门员!
1 2 3 4 5 6 7 8 9 | SELECT f.name AS ForeignKey, OBJECT_NAME(f.parent_object_id) AS TableName, COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName, OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName FROM sys.foreign_keys AS f INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id ORDER BY ReferenceTableName; |
8.)确保在下一步之前,所有表都包含所有PK和FK脚本。
9.)您可以右键单击每个密钥并使用SQL Server 2008编写脚本
10.)使用以下语法从依赖表中删除FK:
1 | ALTER TABLE [dbo].[TABLE_NAME] DROP CONSTRAINT [Name_of_FK] |
11.)删除原始表:
1 | DROP TABLE dbo.table_name_old; |
13.)接下来的步骤依赖于您在步骤9中在SQL Server 2008中创建的脚本。
- 将PK添加到新表中。
- 将FK添加到新表中。
- 将FK添加回依赖关系表。
14.)验证一切正确和完整。我用GUI来查看表格。
15.)将新表重命名为原始表名。
1 | EXEC sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]'; |
最后,一切正常!
正如我在正常情况下所理解的那样,我们正在创建一个具有主键的表,该主键具有标识属性
因此,由于约束规则正在验证列结构,因此无法重命名或删除与主键约束关联的列
要实现这一点,我们必须以下列方式处理一些步骤:
我们假设TableName ='Employee'和ColumnName ='EmployeeId'
1.在"员工"表中添加新列"EmployeeId_new"
ALTER TABLE员工ADD EmployeeId_new INT IDENTITY(1,1)
现在从'Employee'表中删除列'EmployeeId'
ALTER TABLE Employee DROP COLUMN EmployeeId
由于主键约束规则适用并验证列结构,因此会抛出错误。
* ###
'消息5074,级别16,状态1,行1对象[PK_dbo.Employee]依赖于colmn [EmployeeId]。'###
因此,我们必须首先从表'Employee'中删除主键约束,然后我们可以删除该列
ALTER TABLE员工DROP约束[PK_dbo.Employee]
现在我们可以从'Employee'表中删除"EmployeeId"列,就像我们收到错误的上一步一样
ALTER TABLE Employee DROP COLUMN EmployeeId
现在从表中删除了列'EmployeeId'
因此,我们将使用'EmployeeId'重命名新添加的新列'EmployeeId_new'
sp_rename'Employee.EmployeeId','EmployeeId_new','COLUMN'
要以与原来相同的形式重新排列表格,我们必须为"EmployeeId"列添加主键约束
ALTER TABLE员工添加约束[PK_dbo.Employee]主键(EmployeeId)
8.现在,使用'EmployeeId'表'Employee'被修改为Identity规则以及现有的主键约束
根据设计,没有简单的方法来打开或关闭现有列的标识功能。唯一干净的方法是创建一个新列并使其成为标识列或创建新表并迁移数据。
如果我们使用SQL Server Management Studio来删除列"id"上的标识值,则会创建一个新的临时表,将数据移动到临时表,删除旧表并重命名新表。
使用Management Studio进行更改,然后右键单击设计器并选择"生成更改脚本"。
您将看到这是SQL服务器在后台执行的操作。
你不能这样做,你需要添加另一列,删除原始列并重命名新列或创建一个新表,复制数据并删除旧表,然后将新表重命名为旧表表
如果您使用SSMS并在设计器中将identity属性设置为ON,那么SQL Server将在幕后执行此操作。因此,如果您有一个名为[user]的表,那么如果您创建UserID和身份会发生这种情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | BEGIN TRANSACTION SET QUOTED_IDENTIFIER ON SET TRANSACTION ISOLATION LEVEL SERIALIZABLE SET ARITHABORT ON SET NUMERIC_ROUNDABORT OFF SET CONCAT_NULL_YIELDS_NULL ON SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON COMMIT BEGIN TRANSACTION GO GO CREATE TABLE dbo.Tmp_User ( UserID INT NOT NULL IDENTITY (1, 1), LastName VARCHAR(50) NOT NULL, FirstName VARCHAR(50) NOT NULL, MiddleInitial CHAR(1) NULL ) ON [PRIMARY] GO SET IDENTITY_INSERT dbo.Tmp_User ON GO IF EXISTS(SELECT * FROM dbo.[USER]) EXEC('INSERT INTO dbo.Tmp_User (UserID, LastName, FirstName, MiddleInitial) SELECT UserID, LastName, FirstName, MiddleInitialFROM dbo.[User] TABLOCKX') GO SET IDENTITY_INSERT dbo.Tmp_User OFF GO GO DROP TABLE dbo.[USER] GO EXECUTE sp_rename N'dbo.Tmp_User', N'User', 'OBJECT' GO ALTER TABLE dbo.[USER] ADD CONSTRAINT PK_User PRIMARY KEY CLUSTERED ( UserID ) ON [PRIMARY] GO COMMIT |
已经说过有一种方法可以通过设置按位值来破解系统表来实现它,但这是不支持的,我不会这样做
要修改列的标识属性:
-
在"服务器资源管理器"中,右键单击要修改其身份属性的表,然后单击"打开表定义"。
该表在表设计器中打开。 - 清除要更改的列的"允许空值"复选框。
- 在"列属性"选项卡中,展开"标识规范"属性。
- 单击Is Identity子属性的网格单元格,然后从下拉列表中选择"是"。
- 在"标识种子"单元格中键入值。该值将分配给表中的第一行。默认情况下将分配值1。
就是这样,它对我有用
右键单击对象资源管理器中的表名称。你会得到一些选择。点击"设计"。将为此表打开一个新选项卡。您可以在"列属性"中添加标识约束。
遗憾的是,没有一个; IDENTITY属性属于表而不是列。
更简单的方法是在GUI中执行此操作,但如果这不是一个选项,您可以大大复制数据,删除列,重新添加标识,然后重新放回数据。
在这里查看逐个帐户。
如果您碰巧使用Visual Studio 2017+
这将为您完成所有这一切。
如果原始海报实际上想要将现有列设置为表的
1 2 | ALTER TABLE [YourTableName] ADD CONSTRAINT [ColumnToSetAsPrimaryKey] PRIMARY KEY ([ColumnToSetAsPrimaryKey]) |
请注意
虽然这篇文章很老,我正在对请求者的需求做出假设,但我觉得这些额外的信息可能会对遇到这个帖子的用户有所帮助,因为我相信这个对话可能会导致人们相信现有的列不能被设置为主键不首先将其添加为新列,这将是不正确的。
根据我目前的情况,我遵循这种方法。我希望在通过脚本插入数据后为主表提供标识。
因为我想附加身份,所以它总是从1开始到我想要的记录计数结束。
1 2 3 4 5 6 7 8 | --first drop column and add with identity ALTER TABLE dbo.tblProductPriceList DROP COLUMN ID ALTER TABLE dbo.tblProductPriceList ADD ID INT IDENTITY(1,1) --then add primary key to that column (exist option you can ignore) IF NOT EXISTS (SELECT * FROM sys.key_constraints WHERE object_id = OBJECT_ID(N'[dbo].[PK_tblProductPriceList]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblProductPriceList]')) ALTER TABLE [tblProductPriceList] ADD PRIMARY KEY (id) GO |
这将创建具有标识的相同主键列
我用过这个链接:https://blog.sqlauthority.com/2014/10/11/sql-server-add-auto-incremental-identity-column-to-table-after-creating-table/
将主键添加到现有表
为主键= bigint的所有表生成一个脚本,该脚本没有标识集;这将返回每个表生成的脚本列表;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | SET NOCOUNT ON; DECLARE @SQL TABLE(s VARCHAR(MAX), id INT IDENTITY) DECLARE @TABLE_NAME nvarchar(MAX), @table_schema nvarchar(MAX); DECLARE vendor_cursor CURSOR FOR SELECT t.name, s.name FROM sys.schemas AS s INNER JOIN sys.tables AS t ON s.[schema_id] = t.[schema_id] WHERE EXISTS ( SELECT [c].[name] FROM sys.columns [c] JOIN sys.types [y] ON [y].system_type_id = [c].system_type_id WHERE [c].[object_id] = [t].[object_id] AND [y].name = 'bigint' AND [c].[column_id] = 1 ) AND NOT EXISTS ( SELECT 1 FROM sys.identity_columns WHERE [object_id] = t.[object_id] ) AND EXISTS ( SELECT 1 FROM sys.indexes AS [i] INNER JOIN sys.index_columns AS [ic] ON i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id WHERE object_name([ic].[object_id]) = [t].[name] ) OPEN vendor_cursor FETCH NEXT FROM vendor_cursor INTO @TABLE_NAME, @table_schema WHILE @@FETCH_STATUS = 0 BEGIN DELETE FROM @SQL DECLARE @pkname VARCHAR(100), @pkcol nvarchar(100) SELECT top 1 @pkname = i.name, @pkcol = COL_NAME(ic.OBJECT_ID,ic.column_id) FROM sys.indexes AS [i] INNER JOIN sys.index_columns AS [ic] ON i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id WHERE i.is_primary_key = 1 AND OBJECT_NAME(ic.OBJECT_ID) = @TABLE_NAME DECLARE @q nvarchar(MAX) = 'SELECT '+@pkcol+' FROM ['+@table_schema+'].['+@TABLE_NAME+'] ORDER BY '+@pkcol+' DESC' DECLARE @ident_seed nvarchar(MAX) -- Change this to the datatype that you are after SET @q = REPLACE(@q, 'SELECT', 'SELECT TOP 1 @output = ') EXEC sp_executeSql @q, N'@output bigint OUTPUT', @ident_seed OUTPUT INSERT INTO @SQL(s) VALUES ('BEGIN TRANSACTION') INSERT INTO @SQL(s) VALUES ('BEGIN TRY') -- create statement INSERT INTO @SQL(s) VALUES ('create table ['+@table_schema+'].[' + @TABLE_NAME + '_Temp] (') -- column list INSERT INTO @SQL(s) SELECT ' ['+[c].[name]+'] ' + y.name + (CASE WHEN [y].[name] LIKE '%varchar' THEN COALESCE('('+(CASE WHEN ([c].[max_length] < 0 OR [c].[max_length] >= 1024) THEN 'max' ELSE CAST([c].max_length AS VARCHAR) END)+')','') ELSE '' END) + ' ' + CASE WHEN [c].name = @pkcol THEN 'IDENTITY(' +COALESCE(@ident_seed, '1')+',1)' ELSE '' END + ' ' + ( CASE WHEN c.is_nullable = 0 THEN 'NOT ' ELSE '' END ) + 'NULL ' + COALESCE('DEFAULT ('+( REPLACE( REPLACE( LTrim( RTrim( REPLACE( REPLACE( REPLACE( REPLACE( LTrim( RTrim( REPLACE( REPLACE( object_definition([c].default_object_id) ,' ','~') ,')',' ') ) ) ,' ','*') ,'~',' ') ,' ','~') ,'(',' ') ) ) ,' ','*') ,'~',' ') ) + CASE WHEN object_definition([c].default_object_id) LIKE '%get%date%' THEN '()' ELSE '' END + ')','') + ',' FROM sys.columns c JOIN sys.types y ON y.system_type_id = c.system_type_id WHERE OBJECT_NAME(c.[object_id]) = @TABLE_NAME AND [y].name != 'sysname' ORDER BY [c].column_id UPDATE @SQL SET s=LEFT(s,len(s)-1) WHERE id=@@IDENTITY -- closing bracket INSERT INTO @SQL(s) VALUES( ')' ) INSERT INTO @SQL(s) VALUES( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@TABLE_NAME+'_Temp] ON') DECLARE @cols nvarchar(MAX) SELECT @cols = STUFF( ( SELECT ',['+c.name+']' FROM sys.columns c JOIN sys.types y ON y.system_type_id = c.system_type_id WHERE c.[object_id] = OBJECT_ID(@TABLE_NAME) AND [y].name != 'sysname' AND [y].name != 'timestamp' ORDER BY [c].column_id FOR XML PATH ('') ) , 1, 1, '') INSERT INTO @SQL(s) VALUES( 'IF EXISTS(SELECT * FROM ['+@table_schema+'].['+@TABLE_NAME+'])') INSERT INTO @SQL(s) VALUES( 'EXEC(''INSERT INTO ['+@table_schema+'].['+@TABLE_NAME+'_Temp] ('+@cols+')') INSERT INTO @SQL(s) VALUES( 'SELECT '+@cols+' FROM ['+@table_schema+'].['+@TABLE_NAME+']'')') INSERT INTO @SQL(s) VALUES( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@TABLE_NAME+'_Temp] OFF') INSERT INTO @SQL(s) VALUES( 'DROP TABLE ['+@table_schema+'].['+@TABLE_NAME+']') INSERT INTO @SQL(s) VALUES( 'EXECUTE sp_rename N''['+@table_schema+'].['+@TABLE_NAME+'_Temp]'', N'''+@TABLE_NAME+''', ''OBJECT''') IF ( @pkname IS NOT NULL ) BEGIN INSERT INTO @SQL(s) VALUES('ALTER TABLE ['+@table_schema+'].['+@TABLE_NAME+'] ADD CONSTRAINT ['+@pkname+'] PRIMARY KEY CLUSTERED (') INSERT INTO @SQL(s) SELECT ' ['+COLUMN_NAME+'] ASC,' FROM information_schema.key_column_usage WHERE constraint_name = @pkname GROUP BY COLUMN_NAME, ordinal_position ORDER BY ordinal_position -- remove trailing comma UPDATE @SQL SET s=LEFT(s,len(s)-1) WHERE id=@@IDENTITY INSERT INTO @SQL(s) VALUES (' )') END INSERT INTO @SQL(s) VALUES ('--Run your Statements') INSERT INTO @SQL(s) VALUES ('COMMIT TRANSACTION') INSERT INTO @SQL(s) VALUES ('END TRY') INSERT INTO @SQL(s) VALUES ('BEGIN CATCH') INSERT INTO @SQL(s) VALUES (' ROLLBACK TRANSACTION') INSERT INTO @SQL(s) VALUES (' DECLARE @Msg NVARCHAR(MAX) ') INSERT INTO @SQL(s) VALUES (' SELECT @Msg=ERROR_MESSAGE() ') INSERT INTO @SQL(s) VALUES (' RAISERROR(''Error Occured: %s'', 20, 101,@msg) WITH LOG') INSERT INTO @SQL(s) VALUES ('END CATCH') DECLARE @fqry nvarchar(MAX) -- result! SELECT @fqry = (SELECT CHAR(10) + s FROM @SQL ORDER BY id FOR XML PATH ('')) SELECT @TABLE_NAME AS [TABLE_NAME], @fqry AS [Generated_Query] PRINT 'Table: '+@TABLE_NAME EXEC sp_executeSql @fqry FETCH NEXT FROM vendor_cursor INTO @TABLE_NAME, @table_schema END CLOSE vendor_cursor; DEALLOCATE vendor_cursor; |
我不相信您可以使用tsql将现有列更改为标识列。但是,您可以通过企业管理器设计视图执行此操作。
或者,您可以创建一个新行作为标识列,删除旧列,然后重命名新列。
1 2 3 4 | ALTER TABLE FooTable ADD BarColumn INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED |
基本上有四个逻辑步骤。
创建一个新的Identity列。为此新列启用"插入标识"。
将源列(您希望转换为Identity的列)中的数据插入此新列。
关闭新列的"插入标识"。
删除源列并将新列重命名为源列的名称。
可能存在一些更复杂的问题,例如跨多个服务器等工作。
请参阅以下文章了解步骤(使用ssms和T-sql)。这些步骤适用于对T-SQL较少掌握的初学者。
http://social.technet.microsoft.com/wiki/contents/articles/23816.how-to-convert-int-column-to-identity-in-the-ms-sql-server.aspx