使用SELECT * INTO时,新表中的数据类型更改

时间:2016-02-18 10:10:33

标签: sql tsql

我正在处理一个查询,该查询将表结构从链接服务器复制到本地数据库中,以获得通用的表列表。

但由于某种原因,十进制数据类型将更改为数字。在选择过度链接的服务器时,似乎只会发生这种情况。但是,当我在本地系统上尝试相同时,我无法复制问题。

发生此错误的环境本地和链接服务器的SQL版本不同(分别为10,12)。不确定这是否相关。

如果有人能够对此有所了解,那将非常感激。感谢。

查询如下:

WHILE (select count(*) from @tbls) > 0
BEGIN
    SELECT @id = 0, @tblname = '', @cols = '', @colSets = ''
    select top 1 @id = ID, @tblname = TableName, @PKField = PKField, @DataType = DataType from @tbls    

    if exists (select 1 from sys.tables where name = @tblname)
    begin
        delete from @tbls where ID = @id
        Continue;
    end

    exec('select * into '+ @tblname +' from [linkedserver].MyDatabase.dbo.'+@tblname + ' where 1 = 0')

    delete from @tbls where ID = @id
END

2 个答案:

答案 0 :(得分:1)

NUMERICDECIMAL可以互换。但如果这会导致问题,关键可能是在创建表后更改这些列。动态地执行它可能看起来像:

-- Declare a dynamic SQL variable
DECLARE @sql VARCHAR(max)

WHILE (select count(*) from @tbls) > 0
BEGIN
    SELECT @id = 0, @tblname = '', @cols = '', @colSets = ''
    select top 1 @id = ID, @tblname = TableName, @PKField = PKField, @DataType = DataType from @tbls    

    if exists (select 1 from sys.tables where name = @tblname)
    begin
        delete from @tbls where ID = @id
        Continue;
    end

    exec('select * into '+ @tblname +' from [linkedserver].MyDatabase.dbo.'+@tblname + ' where 1 = 0')

    -- After table creation, use row-wise concatenation to create ALTER TABLE statements
    -- Change all numeric to decimal
    SELECT @sql = STUFF((SELECT CHAR(13) + CHAR(10)
                                + CONCAT('ALTER TABLE ALTER COLUMN ', [COLUMN_NAME], ' DECIMAL ', 
                                  '(' + CAST([numeric_precision] AS VARCHAR) + ', ' + CAST([numeric_scale] AS VARCHAR) + ');')
                         FROM   information_schema.columns c
                         WHERE  t.[TABLE_NAME] = c.[TABLE_NAME]
                                AND c.[DATA_TYPE] = 'numeric'
                         ORDER  BY c.[COLUMN_NAME]
                         FOR xml path(''), type).value('.', 'varchar(max)'), 1, 2, '')
    FROM   information_schema.tables t
    WHERE  t.[TABLE_NAME] = @tblname

    -- Run dynamic SQL statement (will sometimes be NULL, which is fine)
    EXEC(@sql)

    delete from @tbls where ID = @id
END

这会将所有 NUMERIC更改为DECIMAL - 这可能不是您想要的。如果是这种情况,您可能需要考虑创建动态CREATE TABLE语句。

答案 1 :(得分:1)

我解决了我的问题我在使用下面的选择后将数字更新为小数:

    declare @lst table (Query varchar(300))

    insert into @lst
    select 'ALTER TABLE '+ TABLE_NAME + ' ALTER COLUMN '+ column_name +' '+
                'decimal' + '('+ cast(NUMERIC_PRECISION as varchar(20)) +','+ cast(NUMERIC_SCALE as varchar(20)) +')' as DataType
    from information_schema.COLUMNS
    where TABLE_NAME = 'Table_Name' and DATA_TYPE = 'numeric'

    while ((select count(*) from @lst) > 0)
    begin
        declare @s varchar(300)
        set @s = (select top 1 query from @lst)
        exec (@s)
        delete from @lst where query = @s
    end

感谢那些回复的人。