啪!贴代码:
-- ============================================= -- Author: 抹茶大虾球丶 -- Create date: 2021-04-27 -- Description: 修改字段类型,带有索引的字段会先删除索引,修改完字段类型后,重建索引 -- exec [grid].[FieldDataTypeModify] \'dbo.table1\',\'Name\',\'varchar(32)\' -- ============================================= alter PROCEDURE [grid].[FieldDataTypeModify] @sTableName sysname, --表名带架构(eg. dbo.table1) @sColumnName sysname, --字段名 @sDataType sysname, --数据类型(eg. int、nvarchar(64)) @result sysname output, --执行结果,0:错误,1:正确 @errmsg sysname output --错误信息 AS BEGIN declare @sSql varchar(max), @sdType sysname, @sdLength int declare @tb_Indexes table(num int,index_name sysname, column_names sysname, column_order sysname, table_view sysname, index_type sysname, unique_type sysname, object_type sysname) declare @tb_Indexes_Bak table(num int,index_name sysname, column_names sysname,column_order sysname, table_view sysname, index_type sysname, unique_type sysname, object_type sysname) declare @nTbRowsCount int --@tb_Indexes数据行数 if not exists (select * from syscolumns a join systypes b on a.xtype=b.xtype where a.ID=object_id(@sTableName) and a.name=@sColumnName) begin set @result=\'0\' set @errmsg=\'字段 \'+@sColumnName+\' 在表 \'+@sTableName+\' 中不存在!\' return; end --获取索引信息 insert into @tb_Indexes select num = row_number() over(order by rg.name), rg.name as index_name, rg.column_names, left(rg.column_order,len(rg.column_order)-1) column_order, rg.table_view, case when rg.[type] = 1 then \'Clustered index\' when rg.[type] = 2 then \'Nonclustered index\' when rg.[type] = 3 then \'XML index\' when rg.[type] = 4 then \'Spatial index\' when rg.[type] = 5 then \'Clustered columnstore index\' when rg.[type] = 6 then \'Nonclustered columnstore index\' when rg.[type] = 7 then \'Nonclustered hash index\' end as index_type, case when rg.is_unique = 1 then \'Unique\' else \'\' --\'Not Unique\' end as unique_type, case when rg.obj_type = \'U\' then \'Table\' when rg.obj_type = \'V\' then \'View\' end as object_type from (select i.[name], substring(column_names, 1, len(column_names)-1) as column_names, column_order, i.[type], i.[is_unique], schema_name(t.schema_id) + \'.\' + t.[name] as table_view, t.[type] as obj_type from sys.objects t inner join sys.indexes i on t.object_id = i.object_id cross apply (select col.[name] + \',\' from sys.index_columns ic inner join sys.columns col on ic.object_id = col.object_id and ic.column_id = col.column_id where ic.object_id = t.object_id and ic.index_id = i.index_id order by key_ordinal for xml path (\'\')) D (column_names) cross apply (select col.[name]+\' \'+ case ic.is_descending_key when 0 then \'ASC\' else \'DESC\' end + \',\' from sys.index_columns ic inner join sys.columns col on ic.object_id = col.object_id and ic.column_id = col.column_id where ic.object_id = t.object_id and ic.index_id = i.index_id order by key_ordinal for xml path (\'\')) D1 (column_order) where t.is_ms_shipped <> 1 and index_id > 0 ) rg where \',\'+column_names+\',\' like \'%,\'+@sColumnName+\',%\' and rg.table_view=@sTableName --select * from @tb_Indexes --删除索引 declare @i int, @idxName sysname set @nTbRowsCount = (select count(*) from @tb_Indexes) if(@nTbRowsCount >0) begin insert into @tb_Indexes_Bak select * from @tb_Indexes while exists(select num from @tb_Indexes) begin set rowcount 1; select @i = num,@idxName=index_name from @tb_Indexes; set @sSql=\'drop index [\'+ @idxName +\'] on \'+ @sTableName exec(@sSql) set rowcount 0; delete from @tb_Indexes where num=@i; end end --修改字段类型 set @sSql = \'alter table \'+@sTableName+\' alter column \'+@sColumnName+\' \'+@sDataType+\'\' exec(@sSql) --重建索引 declare @idxFields sysname, @idxType sysname, @unique sysname set @i=0 set @idxName=\'\' if(@nTbRowsCount >0) begin while exists(select num from @tb_Indexes_Bak) begin set rowcount 1; select @i = num, @idxFields=column_order, @idxName=index_name, @idxType=index_type, @unique=unique_type from @tb_Indexes_Bak; set @sSql=\'create \'+ @unique +\' \'+ @idxType +\' [\'+ @idxName +\'] on \'+ @sTableName + \'(\'+@idxFields+\')\' --print @sSql exec(@sSql) set rowcount 0; delete from @tb_Indexes_Bak where num=@i; end end delete @tb_Indexes delete @tb_Indexes_Bak set @result = \'1\' set @errmsg = \'\' END