Page Top

SqlServer 根据 A 表字段结构创建 B 表或追加字段到 B 表

啪!贴脚本:

declare @sourceSchema varchar(64),   --源表,架构
        @sourceTable varchar(64),    --源表,表名
        @targetSchema varchar(64),   --目标表,架构
        @targetTable varchar(64),    --目标表,表名
        @isAppendMode int,           --是否是追加字段模式,0:创建全新目标表;1:追加表字段模式(目标表必须存在;若有源表主键,仅追加列名)
        @isCopyThorough int          --0:仅字段名和数据类型与源表字段相同,缺省值;1:目标表完全按照源表创建(包括主键、约束等),

set @sourceSchema = 'dbo'
set @sourceTable = 'tb1'
set @targetSchema = 'dbo'
set @targetTable = 'tb2'
set @isAppendMode = 1
set @isCopyThorough = 1

IF OBJECT_ID(''+@sourceSchema+'.'+@sourceTable+'','U') is null
begin
    select '0' as result, '源表不存在!' as errmsg
    return;
end

if(@isCopyThorough not in(0,1))
begin
    select '0' as result, '参数 @isCopyThorough 值无效!值域应为 0 或 1' as errmsg
    return;
end

--drop table [dbo].[R2_test]

declare @sql varchar(max), @i int, @nCount int,
    @column_name sysname, @data_type sysname, @data_length sysname, 
    @is_identity sysname, @default_value sysname, @is_nullable sysname

--源表所有字段
declare @sourceFileds table(
    [num] int,
    [schema_name] sysname null,
    [table_name] sysname null,
    [column_id] sysname null,
    [column_name] sysname null,
    [data_type] sysname null,
    [data_length] sysname null,
    [is_identity] sysname null,
    [default_value] sysname null,
    [is_nullable] sysname null
)

insert into @sourceFileds select 
    ROW_NUMBER() OVER (order by col.column_id asc) as [num],
    schema_name(tab.schema_id) as [schema_name],
    tab.name as table_name, 
    col.column_id,
    col.name as column_name, 
    t.name as data_type,       
    (case cast(c.CHARACTER_MAXIMUM_LENGTH as varchar(6)) when '-1' then 'max' else cast(c.CHARACTER_MAXIMUM_LENGTH as varchar(6)) end) [data_length],  
       case when exists
       (
          SELECT 1 FROM sysobjects where xtype='PK' and name in
           (
               SELECT name FROM sysindexes WHERE indid in
              (
                  SELECT indid FROM sysindexkeys WHERE id=col.object_id AND colid= col.column_id
              )
           )
       ) then 1 else 0 end is_identity,
       c.COLUMN_DEFAULT default_value,
       col.is_nullable
    from sys.tables as tab 
        inner join sys.columns as col on tab.object_id = col.object_id
        left join sys.types as t on col.user_type_id = t.user_type_id 
        left join INFORMATION_SCHEMA.COLUMNS c on c.COLUMN_NAME = col.name and c.TABLE_NAME = tab.name and c.TABLE_SCHEMA = schema_name(tab.schema_id)
        where schema_name(tab.schema_id)+'.'+tab.name = @sourceSchema+'.'+@sourceTable

--select * from @sourceFileds

--1、创建新表模式、仅字段名和数据类型与源表字段相同
--2、创建新表模式、目标表完全按照源表创建(包括主键、约束等)
if(@isAppendMode=0)
begin
    IF OBJECT_ID(''+@targetSchema+'.'+@targetTable+'','U') is not null
    begin
        select '0' as result, '创建新表模式,待创建表已存在!' as errmsg
        return;
    end

    set @sql='create table ['+@targetSchema+'].['+@targetTable+']( '

    set @i=0
    set @nCount= (select count(*) from @sourceFileds)

    while(@i<@nCount)
    begin
        select @column_name=[column_name], @data_type=[data_type], @data_length=[data_length], 
            @is_identity=[is_identity], @default_value=[default_value], @is_nullable=[is_nullable] 
        from @sourceFileds
        where 
            num=@i+1
    
        set @sql = @sql+ '['+@column_name+'] '+@data_type+' '  --eg. create table dbo.tb( [fd_01] char 
        
        if(isnull(@data_length,'') <> '')
        begin
            set @sql=@sql+'('+@data_length+') '       --eg. create table dbo.tb( [fd_01] char (1) 
        end            
        
        --目标表完全按照源表创建、源表字段是int型主键,创建目标表int自增主键
        if(@isCopyThorough=1 and @is_identity='1' and @data_type='int')
        begin
            --eg. create table dbo.tb( [ID] int identity(1,1) not null constraint [PK_ID] primary key clustered ([ID] asc),
            set @sql=@sql+'identity(1,1) not null constraint [PK_'+@targetTable+'] primary key clustered (['+@column_name+'] asc) ' 
        end
        else                           
        begin
            --print @is_nullable
            if (@is_nullable='1' or (@is_nullable='0' and @isCopyThorough=0))     --字段可为空 || 仅字段名和数据类型与源表字段相同
            begin                                       
                set @sql=@sql+'null '     --eg. create table dbo.tb( [fd_01] char (1) null
            end                                           
            else                                       
            begin                                       
                set @sql=@sql+'not null '     --eg. create table dbo.tb( [fd_01] char (1) not null
    
                --字段默认值
                if(isnull(@default_value,'') <> '')
                begin
                    --eg. create table dbo.tb( [fd_01] char (2) not null constraint [DF_tb_Deleted] default ('T'),
                    set @sql=@sql+'constraint [DF_'+@targetTable+'_'+@column_name+'] default '+@default_value+' '  
                end
            end
        end                                       
    
        set @sql=@sql+','
        set @i=@i+1
    end

    set @sql=@sql+') on [PRIMARY]'
    print @sql

    exec(@sql)

    select '1' as result, '' as errmsg
    return;
end;
--3、追加表字段模式
else if(@isAppendMode=1)
begin
    IF OBJECT_ID(''+@targetSchema+'.'+@targetTable+'','U') is null
    begin
        select '0' as result, '追加表字段模式,目标表不存在!' as errmsg
        return;
    end;

    --需要追加到目标表的字段
    declare @requireAddFileds table(
        [num] int,
        [schema_name] sysname null,
        [table_name] sysname null,
        [column_id] sysname null,
        [column_name] sysname null,
        [data_type] sysname null,
        [data_length] sysname null,
        [is_identity] sysname null,
        [default_value] sysname null,
        [is_nullable] sysname null
    );
    
    with
    targetFields as
    (
        select col.name as column_name 
            from sys.tables as tab 
                inner join 
                    sys.columns as col on tab.object_id = col.object_id
            where schema_name(tab.schema_id)+'.'+tab.name = @targetSchema+'.'+@targetTable  
    )
    
    --取源表、目标表字段差集,结果为目标表中不存在的字段
    insert into @requireAddFileds select ROW_NUMBER() OVER (order by a.column_id asc) as [num], a.[schema_name],
            a.[table_name], a.[column_id], a.[column_name], a.[data_type], a.[data_length], a.[is_identity],
            a.[default_value], a.[is_nullable]
        from @sourceFileds a
        join
            (select column_name from @sourceFileds
                except 
             select column_name from targetFields) b
        on a.column_name=b.column_name order by a.column_id 
    
    --select * from @requireAddFileds
    
    set @i=0
    set @nCount= (select count(*) from @requireAddFileds)
    
    while(@i<@nCount)
    begin
        select @column_name=[column_name], @data_type=[data_type], @data_length=[data_length], 
            @is_identity=[is_identity], @default_value=[default_value], @is_nullable=[is_nullable] 
        from @requireAddFileds 
        where num=@i+1
    
        set @sql = 'alter table ['+@targetSchema+'].['+@targetTable+'] add '+@column_name+' '+@data_type+' '  --eg. alter table [dbo].[tb] add [fd_01] char 
        
        if(isnull(@data_length,'') <> '')
        begin
            set @sql=@sql+'('+@data_length+') '       --eg. alter table [dbo].[tb] add [fd_01] char (1) 
        end                                           
                                                   
        if (@is_nullable='1' or (@is_nullable='0' and @isCopyThorough=0))     --字段可为空 || 仅字段名和数据类型与源表字段相同
        begin                                       
            set @sql=@sql+'null '     --eg. alter table [dbo].[tb] add [fd_01] char (1) null
        end                                           
        else                                       
        begin                                       
            set @sql=@sql+'not null '     --eg. alter table [dbo].[tb] add [fd_01] char (1) not null
    
            if(isnull(@default_value,'') <> '')
            begin
                --eg. alter table [dbo].[tb] add [fd_01] char (2) not null constraint [DF_tb_Deleted] default ('T')
                set @sql=@sql+'constraint [DF_'+@targetTable+'_'+@column_name+'] default '+@default_value+''  
            end
        end
    
        --print @sql;
    
        exec(@sql)
    
        set @i=@i+1
    end
    
    select '1' as result, '' as errmsg
    return;
end
else
begin
    select '0' as result, '参数 @isAppendMode 值无效!值域应为 0 或 1' as errmsg
end

 

posted @ 2021-11-24 15:12  抹茶大虾球丶  阅读(378)  评论(0编辑  收藏  举报