I'm working on a query that copies the table structure from a linked server into the local database for a generic list of tables.
However for some reason the decimal data types are getting changed to numeric. This only seemed to be happening when selecting into over linked servers. However when trying the same on my local system I could not replicate the problem.
The environment where this error happened the SQL version of the local and linked server were different (10, 12 respectively). Not sure if that's related.
If anyone could shed some light on this it would be much appreciated. Thanks.
The query is as per below:
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
NUMERIC
and DECIMAL
are interchangeable. But if this causes issues, the key may be to alter those columns after the table is created. Doing it dynamically could look something like:
-- 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
This will change all NUMERIC
to DECIMAL
- which may not be what you want. If that's the case, you might have to look into creating a dynamic CREATE TABLE
statement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With