Page Top

Sqlserver 修改字段类型

啪!贴代码:

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

 

posted @ 2021-11-26 11:56  抹茶大虾球丶  阅读(1509)  评论(0编辑  收藏  举报