SP用于比较两个表的列和数据类型,并根据源表更改目标表

时间:2017-06-13 10:17:25

标签: sql-server stored-procedures

我基本上是SQL的新手,我有一个创建存储过程的请求来比较两个表(源表和目标表)的列。

所以首先在两个被比较的表(源表和目标表)中,如果没有公共列,那么我需要调用一个CREATE TABLE过程来在目标数据库或目标中创建源表架构。我还需要帮助来创建CREATE TABLE过程。

在下一种情况下,如果两个表中存在匹配的列,我们需要比较列。因此,如果在源表中,可能有两个或三个额外的列(甚至更多)与目标表相比较我需要更改目标表以便添加这两个或三个列,我还需要根据源表更改目标表的数据类型(对于这些添加的列)。类似地,如果在目标表中与源表相比有两个或三个额外的列(或更多),那么我需要从目标表中删除这些列。因此,在这些情况下,我还需要帮助调用ALTER TABLE过程。

有人可以帮我处理存储过程吗?

1 个答案:

答案 0 :(得分:0)

没有声称这是完美的,而且我的命名惯例很糟糕,但是我把它弄糟了,所以想和你分享,因为我希望它能让你开始:

DECLARE @strTargetTable     NVARCHAR(20)    ,
        @strSourceTable     NVARCHAR(20)    ,
        @intCommonColumns   INT;

SELECT  @strTargetTable = 'Test_Table';
SELECT  @strSourceTable = 'Test1';


SELECT  @intCommonColumns = COUNT(*)
FROM
(
    SELECT  TD3.COLUMN_NAME
    FROM    Test_Database3.INFORMATION_SCHEMA.COLUMNS AS TD3
    WHERE   TD3.TABLE_NAME  = @strTargetTable
    AND     EXISTS
    (
    SELECT  TD.COLUMN_NAME
    FROM    Test_Database3.INFORMATION_SCHEMA.COLUMNS   AS TD
    WHERE   TD.TABLE_NAME   = @strSourceTable
    AND     TD3.COLUMN_NAME = TD.COLUMN_NAME
    )
) AS A

/*No common columns*/
IF(@intCommonColumns = 0)
    BEGIN
        PRINT 'Create table here';
    END

/*Common Columns*/
IF(@intCommonColumns > 0)
    BEGIN 
        /*There are matching columns so figure out what to do with them*/

        /*Create table to hold the columns that need creating*/
        IF OBJECT_ID('tempdb..#tmpCreateFirstColumns') IS NOT NULL DROP TABLE #tmpCreateFirstColumns
        CREATE TABLE #tmpCreateFirstColumns
        (
            ID          INT IDENTITY(1,1)       ,
            T_COL_NAME  NVARCHAR(20)            ,
            T_DATA_TYPE NVARCHAR(20)
        )
        INSERT INTO #tmpCreateFirstColumns
        (
            T_COL_NAME  ,
            T_DATA_TYPE
        )
        /*Get columns from the Source table that don't exist in the target*/
        SELECT  TD3.COLUMN_NAME ,
                TD3.DATA_TYPE + CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NULL THEN '' ELSE '('+CAST(CHARACTER_MAXIMUM_LENGTH AS NVARCHAR(3))+')' END   
        FROM    Test_Database3.INFORMATION_SCHEMA.COLUMNS AS TD3
        WHERE   TD3.TABLE_NAME  = @strSourceTable
        AND     NOT EXISTS
        (
        SELECT  TD.COLUMN_NAME
        FROM    Test_Database3.INFORMATION_SCHEMA.COLUMNS   AS TD
        WHERE   TD.TABLE_NAME   = @strTargetTable
        AND     TD3.COLUMN_NAME = TD.COLUMN_NAME
        )

        DECLARE @intMinID   INT ,
                @intMaxID   INT ,
                @strSQL     NVARCHAR(MAX);

        SELECT  @intMinID = MIN(TC.ID)  ,
                @intMaxID = MAX(TC.ID)
        FROM    #tmpCreateFirstColumns  AS TC

        WHILE(@intMinID <= @intMaxID)
            BEGIN
                DECLARE @strCol NVARCHAR(20)    ,
                        @strData1   NVARCHAR(MAX)   ;

                SELECT  @strCol         =   TC.T_COL_NAME   ,
                        @strData1       =   TC.T_DATA_TYPE
                FROM    #tmpCreateFirstColumns      AS TC
                WHERE   TC.ID = @intMinID;

                SELECT  @strSQL = 'ALTER TABLE '+@strTargetTable+' ADD '+'['+@strCol+']'+' '+@strData1;
                PRINT 'ALTER TABLE '+@strTargetTable+' ADD '+'['+@strCol+']'+' '+@strData1;
                EXEC    sp_executesql @strSQL

                SELECT @intMinID = @intMinID + 1;
            END

        /*Create table to hold the columns that need creating*/
        IF OBJECT_ID('tempdb..#tmpCreateColumns') IS NOT NULL DROP TABLE #tmpCreateColumns
        CREATE TABLE #tmpCreateColumns
        (
            ID          INT IDENTITY(1,1)       ,
            T_COL_NAME  NVARCHAR(20)            ,
            T_DATA_TYPE NVARCHAR(20)
        )
        INSERT INTO #tmpCreateColumns
        (
            T_COL_NAME  ,
            T_DATA_TYPE
        )
        /*Get columns from the Source table that don't exist in the target*/
        SELECT  TD3.COLUMN_NAME ,
                TD3.DATA_TYPE + CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NULL THEN '' ELSE '('+CAST(CHARACTER_MAXIMUM_LENGTH AS NVARCHAR(3))+')' END   
        FROM    Test_Database3.INFORMATION_SCHEMA.COLUMNS AS TD3
        WHERE   TD3.TABLE_NAME  = @strTargetTable
        AND     NOT EXISTS
        (
        SELECT  TD.COLUMN_NAME
        FROM    Test_Database3.INFORMATION_SCHEMA.COLUMNS   AS TD
        WHERE   TD.TABLE_NAME   = @strSourceTable
        AND     TD3.COLUMN_NAME = TD.COLUMN_NAME
        )

        SELECT  @intMinID = MIN(TCC.ID) ,
                @intMaxID = MAX(TCC.ID)
        FROM    #tmpCreateColumns       AS TCC

        WHILE(@intMinID <= @intMaxID)
            BEGIN
                DECLARE @strCol2    NVARCHAR(20)    ,
                        @strData    NVARCHAR(MAX)   ;

                SELECT  @strCol2        =   TCC.T_COL_NAME  ,
                        @strData    =   TCC.T_DATA_TYPE
                FROM    #tmpCreateColumns       AS TCC
                WHERE   TCC.ID = @intMinID;

                SELECT  @strSQL = 'ALTER TABLE '+@strSourceTable+' ADD '+'['+@strCol2+']'+' '+@strData;
                PRINT 'ALTER TABLE '+@strSourceTable+' ADD '+'['+@strCol2+']'+' '+@strData;
                EXEC    sp_executesql @strSQL

                SELECT @intMinID = @intMinID + 1;
            END
        END