2016-02-18 8 views
5

Pracuję nad zapytaniem, które kopiuje strukturę tabeli z połączonego serwera do lokalnej bazy danych dla ogólnej listy tabel.Zmiany typu danych w nowej tabeli podczas korzystania z SELECT * INTO

Jednak z jakiegoś powodu dziesiętne typy danych zmieniają się na liczbowe. Wydaje się, że zdarza się to tylko przy wybieraniu serwerów połączonych. Jednak przy próbie tego samego w moim lokalnym systemie nie mogłem replikować problemu.

Środowisko, w którym wystąpił ten błąd, wersja SQL serwera lokalnego i połączonego były inne (odpowiednio 10, 12). Nie wiem, czy to jest powiązane.

Jeśli ktokolwiek mógłby rzucić trochę światła na to, byłoby to bardzo cenne. Dzięki.

Zapytanie jest za poniżej

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

W serwerze SqlServer wie, że zestawy znaków i formaty są takie same. Więc zachowuje źródło. Między różnymi serwerami zwykle domyślnie rzutuje wszystkie typy danych na najwyższy wspólny mianownik dla każdego typu danych. Ponieważ próbujesz utworzyć tabelę bez danych, zobacz ten wątek: http://stackoverflow.com/questions/21547/in-sql-server-how-do-i-generate-a-create-table-statement- for-a-given-table –

+0

Sezonowy duplikat http://stackoverflow.com/questions/33513776/sql-auto-converts-decimal-to-numeric-when-select-insert –

+0

@AndreeaDumitru To może być duplikat, ale jedna odpowiedź na nie nie odpowiada. Żadna z tych odpowiedzi nie została zaakceptowana ... –

Odpowiedz

1

mi rozwiązać mój problem mój aktualizowania tabeli z numeryczne do dziesiętnych po select into używając poniżej:

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 

Dzięki dla tych, którzy odpowiedzieli.

1

NUMERIC i DECIMAL są wymienne. Ale jeśli powoduje to problemy, kluczem może być zmiana tych kolumn po utworzeniu tabeli. Robi to dynamicznie mogłaby wyglądać następująco:

-- 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 

Spowoduje to zmianę wszystkoNUMERIC do DECIMAL - który nie może być to, co chcesz. W takim przypadku może zajść potrzeba stworzenia instrukcji dynamicznej CREATE TABLE.

Powiązane problemy