zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    delphi shr和shl的作用
    delphi socket 编程 使用多线程
    mysql 移除服务,并在cmd下切换目录
    delphi 结构体和TList的用法
    delphi 使用工控机控件 iThreadTimes 出现问题, 导致主程序创建页面的时候, 阻塞消息, 不能正常执行。
    Unicode 和 UTF-8 的区别
    Python 模块 re (Regular Expression)
    Python的函数式编程
    反向解析与PTR(Pointer Record)
    simhash算法
  • 原文地址:https://www.cnblogs.com/seanyan/p/15598204.html
Copyright © 2011-2022 走看看