您的位置:首页 > 其它

修改表主键字段数据类型(up_ModifyPrimaryColumn)

2012-12-10 11:58 459 查看
开始:

有一需求,就是把表中作为主键字段的数据类型从int 转换为 uniqueidentifier。我们可能会想到直接通过Microsoft SQL Server Management Studio (MSSMS)修改表结构,删除原来的主键,增加一个数据类型为uniqueidentifier的字段作为主键,并对它设置not null default(newid()) 。

对于单独的表,主键没有被其他表作为外键,可以这样修改,但一旦存在外键时,我们就不能这样修改了。至少我们需要通过编写T-SQL语句来实现,基本方法是:

1.删除外键约束

2.修改表字段类型(删除主键约束-->新增uniqueidentifier类型的字段(default(newid())),并设置为主键)

3.在其他表(原主键字段,在其他表作为外键的表)新增uniqueidentifier类型的字段(default(newid()))。

4.更新数据

5.字段重新命名

6.重新创建外键

当然你还要考虑索引是否要重新创建,如果我们要修改一大堆的表,那么需要写一大堆的T-SQl代码。

为了解决这一问题,这里我为此特别写了一个存储过程up_ModifyPrimaryColumn来实现表主键数据类型转换。

up_ModifyPrimaryColumn应用范围:

1.作为主键的字段必须是单一字段

2.不考虑分区

存储过程up_ModifyPrimaryColumn:

View Code

Use [test]
Go
If object_id('[FK_TableB_TableA_ID]') Is Not Null Alter Table [TableB] Drop Constraint [FK_TableB_TableA_ID]
Go
If object_id('[PK_TableB]') Is Not Null Alter Table [TableB] Drop Constraint [PK_TableB]
Go
If object_id('[PK_TableA]') Is Not Null Alter Table [TableA] Drop Constraint [PK_TableA]
Go
If Exists(Select 1 From sys.indexes Where object_id=object_id('TableB') And name='PK_TableB') Drop Index [TableB].[PK_TableB]
If Exists(Select 1 From sys.indexes Where object_id=object_id('TableB') And name='IX_TableB_TableA_ID') Drop Index [TableB].[IX_TableB_TableA_ID]
If Exists(Select 1 From sys.indexes Where object_id=object_id('TableA') And name='PK_TableA') Drop Index [TableA].[PK_TableA]
If Exists(Select 1 From sys.indexes Where object_id=object_id('TableA') And name='IX_TableA_Code') Drop Index [TableA].[IX_TableA_Code]
Go
If Object_id('Tempdb..[#TableA]') Is Not Null Drop Table [#TableA]
Select *,Newid() As [ID_new] Into [#TableA] From [TableA]
If Object_id('Tempdb..[#TableB]') Is Not Null Drop Table [#TableB]
Select *,Convert(uniqueidentifier,null) As [TableA_ID_new] Into [#TableB] From [TableB]
Go
Update a Set a.[TableA_ID_new]=b.[ID_new] From [#TableB] As a Inner Join [#TableA] As b On b.[ID]=a.[TableA_ID]
Go
If Object_id('[TableA_new]') Is Not Null Drop Table [TableA_new]
Create Table [TableA_new]
(
ID uniqueidentifier Rowguidcol Not null
,[Code] nvarchar(50) Null
,[Data] nvarchar(50) Null

)
If Object_id('[TableB_new]') Is Not Null Drop Table [TableB_new]
Create Table [TableB_new]
(
[ID] int Identity(1,1) Not Null
,[TableA_ID] uniqueidentifier Not Null
,[Data] nvarchar(50) Null

)
Go
Insert Into [TableA_new] ([ID],[Code],[Data]) Select [ID_new],[Code],[Data] From [#TableA]
Set Identity_insert [TableB_new] On
Insert Into [TableB_new] ([ID],[TableA_ID],[Data]) Select [ID],[TableA_ID_new],[Data] From [#TableB]
Set Identity_insert [TableB_new] Off
Go
If object_id('[TableB]') Is Not Null
Drop Table [#TableB]
If object_id('[TableA]') Is Not Null
Drop Table [#TableA]
Go
Begin Try
Begin Transaction
If object_id('[TableB]') Is Not Null And object_id('[TableB20121210]') Is Null Exec sp_rename 'TableB','TableB20121210','OBJECT'
If object_id('[TableA]') Is Not Null And object_id('[TableA20121210]') Is Null Exec sp_rename 'TableA','TableA20121210','OBJECT'
If object_id('[TableB_new]') Is Not Null And object_id('[TableB]') Is Null  Exec sp_rename 'TableB_new','TableB','OBJECT'
If object_id('[TableA_new]') Is Not Null And object_id('[TableA]') Is Null  Exec sp_rename 'TableA_new','TableA','OBJECT'
Commit Transaction
End Try
Begin Catch
Print N'重命名表的時候發生錯誤!'
Rollback Transaction
End Catch
Go
If object_id('[PK_TableA]') Is Null Alter Table [TableA] Add Constraint [PK_TableA] Primary Key CLUSTERED ([ID] Asc)
If object_id('[PK_TableB]') Is Null Alter Table [TableB] Add Constraint [PK_TableB] Primary Key CLUSTERED ([ID] Asc)
If object_id('[FK_TableB_TableA_ID]') Is Null Alter Table [TableB] With Check Add Constraint [FK_TableB_TableA_ID] Foreign Key ([TableA_ID]) References [TableA]([ID]) On Delete NO ACTION On Update NO ACTION
Go
Create  NONCLUSTERED Index [IX_TableA_Code] On [TableA] ([Code])
Create  NONCLUSTERED Index [IX_TableB_TableA_ID] On [TableB] ([TableA_ID])
Go


执行生成的脚本,



并检查转换后的结果:

use test
Go
select * From TableA;
select * From TableB;
go




小结:

up_ModifyPrimaryColumn已在SQL Server 2005/2008/2008R2作测试通过。在这篇随笔中,我只是描述功能的实现,没有对存储过程up_ModifyPrimaryColumn进行详细的说明,也许里面有些地方写的,与你实际应用的时候有些出入,你可以修改其中的代码来满足实际的需求。如果你对其中的内容感兴趣,哪里有疑问或建议,可以发email或在文章后面的回复中与我联系,非常感谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: