seanyan

啪!贴代码:

-- =============================================
-- 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

 

分类:

技术点:

相关文章: