批量修改欄位長度,考慮主鍵外來鍵索引的情況【轉】

47328983發表於2011-04-18
/*====================================================*/
-- Author: 黃光偉
--
Create date: 2010-06-03 21:00:02
--
Description:    批量修改欄位長度,考慮待修改欄位為主鍵或者外來鍵或者索引的情況 使用sp_helpindex列出索引資訊
--
        版本 MSSQL2000
       
/*====================================================*/

--引數資訊
declare @colname varchar(50)--欄位名稱
declare @length int --長度
declare @type varchar(20)--型別 --未考慮待完善
declare @addlen int--是否有長度 --未考慮待完善

 

--賦值
select @colname = 'TboxName',
    @length = 50

declare @tablename varchar(50),@sql varchar(8000),@exec varchar(8000)
declare @pkname varchar(100)--主鍵名
declare @pkfieldname varchar(500) --主鍵欄位名
declare @isnullable char(1) -- 是否為空
declare @foreignkey varchar(100)--外來鍵名
declare @foreignname varchar(500) --外來鍵欄位名
declare @displayname varchar(500) --外來鍵對應欄位名
declare @displaytable varchar(50) --外來鍵對應表名
declare @display varchar(50) --外來鍵對應欄位
declare @isnull char(1) -- 外來鍵對應欄位是否為空

--索引臨時表
create table #index(
index_name varchar(50),
index_declare varchar(500),
index_keys varchar(300)
)

--start
select t.name,r.isnullable into #temp from sysobjects t,syscolumns r
where t.id = r.id and t.xtype = 'U' and
r.name = @colname --and r.length = 20

declare cursor_temp cursor for
--含該欄位的表
select * from #temp
open cursor_temp
fetch  cursor_temp into @tablename,@isnullable
while @@fetch_status = 0
begin
    begin tran
    --初始化
    select @pkfieldname = '',@pkname = '',@foreignkey='',@foreignname='',
            @displayname = '',@displaytable='',@display= ''

    --清空索引臨時表
    truncate table #index

    --插入索引資訊
    insert into #index
    exec sp_helpindex @tablename

    --判斷主鍵是否存在該欄位
    if exists(select 1 from #index where charindex('primary key',index_declare) > 0 and
            charindex(','+@colname+',',','+replace(rtrim(ltrim(index_keys)),', ',',')+',') > 0)
    begin
        select @pkname = index_name,@pkfieldname = index_keys from #index
        where charindex('primary key',index_declare) > 0 and
            charindex(','+@colname+',',','+replace(rtrim(ltrim(index_keys)),', ',',')+',') > 0
        --刪除主鍵
        set @sql = 'alter table '+ @tablename + ' drop constraint ' + @pkname
              print @sql+char(13)+char(10)+'go'    
        exec(@sql)
    end
    --重建主鍵另一方法
    /*
        -- 取得主鍵名
        select @pkname = name from sysobjects where xtype = 'PK'
              and parent_obj = object_id(@tablename,'U')
    
    --判斷主鍵是否存在該欄位
    if exists(select 1 from sysindexkeys ,syscolumns,sysindexes
            where sysindexkeys.colid = syscolumns.colid and
                sysindexkeys.id = syscolumns.id and
                sysindexkeys.indid = sysindexes.indid and
                sysindexkeys.id = sysindexes.id and
                sysindexes.name = @pkname and syscolumns.name = @colname)
    begin
               -- 主鍵欄位
        select @pkfieldname = @pkfieldname+syscolumns.name+',' from sysindexkeys ,syscolumns,sysindexes
                where sysindexkeys.colid = syscolumns.colid and
                    sysindexkeys.id = syscolumns.id and
                    sysindexkeys.indid = sysindexes.indid and
                    sysindexkeys.id = sysindexes.id and
                    sysindexes.name = @pkname
               -- 刪除舊主鍵
               set @sql = 'alter table '+ @tablename + ' drop constraint ' + @pkname
              print @sql+char(13)+char(10)+'go'
               exec(@sql)    
    end
    */

    --判斷索引是否存在該欄位
    if exists(select 1 from #index where charindex('primary key',index_declare) = 0 and
            charindex(','+@colname+',',','+replace(rtrim(ltrim(index_keys)),', ',',')+',') > 0)
    begin
        select @sql = '',@exec = ''
        
        select @sql = @sql + char(13)+char(10)+'drop index dbo.'+@tablename+'.'+index_name+char(13)+char(10)
        from #index where charindex(','+@colname+',',','+replace(rtrim(ltrim(index_keys)),', ',',')+',') > 0 and
                    charindex('primary key',index_declare) = 0
        --刪除索引
        print @sql+'go'
        exec(@sql)
        
        --索引語法
        /*create  unique  index [ix_pln_cost_limit] on [dbo].[pln_cost_limit]([task_no], [mat_code]) on [primary]*/
        select @exec = @exec+char(13)+char(10)+'create '+
                case charindex('unique',index_declare) when 0 then 'index ' else 'unique index ' end +
                index_name+' on '+@tablename+'('+replace(index_keys,'(-)',' desc ')+') on [primary]'+char(13)+char(10)
        from #index where charindex(','+@colname+',',','+replace(rtrim(ltrim(index_keys)),', ',',')+',') > 0 and
                    charindex('primary key',index_declare) = 0

    end

        -- 取得外來鍵名
        select @foreignkey = name from sysobjects where xtype = 'F'
              and parent_obj = object_id(@tablename,'U')

    select @displaytable = name from sysobjects where xtype = 'U' and
        id = (select top 1 rkeyid from sysforeignkeys
            where constid = object_id(@foreignkey,'F'))

    --判斷外來鍵是否存在該欄位
    if exists(select 1 from sysforeignkeys t,syscolumns r,syscolumns f
            where t.fkeyid = r.id and t.fkey = r.colid and
            t.rkeyid = f.id and t.rkey = f.colid and
            t.constid = object_id(@foreignkey,'F') and r.name = @colname)
    begin
        -- 外來鍵欄位
        select @foreignname = @foreignname+r.name+',',@displayname = @displayname + f.name+','
            from sysforeignkeys t,syscolumns r,syscolumns f
            where t.fkeyid = r.id and t.fkey = r.colid and
            t.rkeyid = f.id and t.rkey = f.colid and
            t.constid = object_id(@foreignkey,'F')
        --對應欄位名
        select @display = f.name from sysforeignkeys t,syscolumns r,syscolumns f            
        where t.fkeyid = r.id and t.fkey = r.colid and
            t.rkeyid = f.id and t.rkey = f.colid and
            t.constid = object_id(@foreignkey,'F') and r.name = @colname
           -- 刪除外來鍵
           set @sql = 'alter table '+ @tablename + ' drop constraint ' + @foreignkey
          print @sql+char(13)+char(10)+'go'
           exec(@sql)    
    end

    --修改欄位長度
    select @sql = 'alter table ' + @tablename + ' alter column '+@colname+' varchar('+
                    rtrim(@length)+') ' + case @isnullable when '1' then 'null' else 'not null' end
    print @sql+char(13)+char(10)+'go'
    exec(@sql)

    -- 建立主鍵
    if isnull(@pkfieldname,'') <> ''
    begin
            set @sql =  'alter table ' + @tablename + ' add constraint ' + @pkname
                            +  ' primary key clustered(' + @pkfieldname + ') on [primary]'
        print @sql+char(13)+char(10)+'go'    
            exec(@sql)
    
    end
    --重建索引
    if isnull(@exec,'') <> ''
    begin
        print @exec+'go'
        exec(@exec)
        select @exec = ''
    end

    -- 建立外來鍵
    /*
    建立語法
    ALTER TABLE [dbo].[wrkshop_check] ADD CONSTRAINT [wrk_mat_code] FOREIGN KEY
    (
        [mat_code]
    ) REFERENCES [MAT_MASTER] (
        [MAT_CODE]
    )
    */
    if @foreignname <> ''
    begin
        --構建外來鍵欄位長度需一致
        --修改外來鍵對應表的欄位長度
        --是否為空
        select @isnull = isnullable from syscolumns where id = object_id(@displaytable,'U') and name = @display
        --修改長度
        select @sql = 'alter table ' + @displaytable + ' alter column '+@display+' varchar('+
                        rtrim(@length)+') ' + case @isnull when '1' then 'null' else 'not null' end
        print @sql+char(13)+char(10)+'go'
        exec(@sql)
        delete from #temp where name = @displaytable
        --重建外來鍵
        select @foreignname = left(@foreignname,len(@foreignname) - 1),
            @displayname = left(@displayname,len(@displayname) - 1)        
            set @sql =  'alter table ' + @tablename + ' add constraint ' + @foreignkey
                            +  ' foreign key (' + @foreignname + ') REFERENCES '
                + @displaytable + '('+@displayname+')'
        print @sql+char(13)+char(10)+'go'    
            exec(@sql)
        
    end

    if @@error > 0
    begin
        rollback tran
        
        close cursor_temp
        deallocate cursor_temp

        drop table #index
        return
    end
    else
    begin
        print '-----------------------------'
        commit tran
        fetch next from cursor_temp into @tablename,@isnullable
    end
end
close cursor_temp
deallocate cursor_temp

drop table #index,#temp

 

批量修改欄位長度,考慮主鍵外來鍵索引的情況【轉】 <!--

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/241379/viewspace-692773/,如需轉載,請註明出處,否則將追究法律責任。

相關文章