2016-02-18 2 views
5

Я работаю над запросом, который копирует структуру таблицы из связанного сервера в локальную базу данных для общего списка таблиц.Изменения типа данных в новой таблице при использовании SELECT * INTO

Однако по какой-либо причине десятичные типы данных изменяются на числовые. Похоже, что это происходит при выборе на более связанных серверах. Однако, когда я пытаюсь сделать то же самое в своей локальной системе, я не смог бы воспроизвести проблему.

Окружающая среда, в которой произошла эта ошибка, 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.'[email protected] + ' where 1 = 0') 

    delete from @tbls where ID = @id 
END 
+2

В вашем сервере SqlServer знает, что наборы символов и форматы одинаковы. Таким образом, он сохраняет источник. Между разными серверами он обычно неявно отбрасывает все типы данных до самого высокого общего знаменателя для каждого типа данных. Поскольку вы просто пытаетесь создать таблицу без данных, см. Этот поток http://stackoverflow.com/questions/21547/in-sql-server-how-do-i-eneration-a-create-table-statement- for-a-given-table –

+0

Положительный дубликат http://stackoverflow.com/questions/33513776/sql-auto-converts-decimal-to-numeric-when-select-insert –

+0

@AndreeaDumitru Это может быть дубликат, но один ответ на это не отвечает. Также не был принят ответ ... –

ответ

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 

Спасибо за тех, кто ответил.

1

NUMERIC и DECIMAL являются взаимозаменяемыми. Но если это вызывает проблемы, ключевым может быть изменение этих столбцов после создания таблицы. Делать это динамически может выглядеть примерно так:

-- 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.'[email protected] + ' 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.

Смежные вопросы