2016-06-01 3 views
1

Я пытаюсь использовать динамический SQL для заполнения временной таблицы данными с одного из нескольких серверов, в зависимости от объявленной переменной. У исходных данных может быть больше столбцов, добавленных в будущем, поэтому я хотел бы иметь возможность создавать временную таблицу назначения на основе того, какие столбцы существуют в настоящее время, без необходимости явно определять ее.Создать таблицу на лету, используя select в

Я попытался создать пустую таблицу с соответствующими столбцами с помощью:

Select top 1 * into #tempTable from MyTable 
Delete from #tempTable 

Или:

Select * into #tempTable from MyTable where 1 = 0 

Оба работали, чтобы создать пустую таблицу, но когда я затем попытаться вставить в него:

declare @sql varchar(max) = 'Select * from ' 
+ case when @server = '1' then 'Server1.' else 'Server2.' end 
+ 'database.dbo.MyTable' 

Insert into #tempTable 
    exec(@sql) 

Я получаю эту ошибку:

Msg 213, Level 16, State 7, Line 1 Column name or number of supplied values does not match table definition.

exec(@sql) работает отлично самостоятельно. Я получаю эту ошибку, даже когда я использую одну и ту же таблицу на том же сервере для обоих шагов. Можно ли это исправить, или мне нужно вернуться к прямому определению таблицы с помощью create table?

+0

ли пользователь вы подключаетесь с есть таблица «MyTable» в это схема, которая структурно отличается чем на server1 или server2? – xQbert

+0

Нет. Я попробовал это с тем же сервером и таблицей как в 'select into', так и' insert into', и просто выберите из #tempTable и MyTable для сравнения. Они кажутся одинаковыми. – APH

+1

Я не думал, что вы не можете комбинировать вставку и exec таким образом. все это должен быть динамический SQL или ни один из них. try 'exec ('Insert into #tempTable' + @sql)' – xQbert

ответ

1

Как насчет использования глобальной таблицы темп. существует некоторый недостаток использования глобальной таблицы temp, поскольку он может получать доступ от нескольких пользователей и баз данных. исх http://sqlmag.com/t-sql/temporary-tables-local-vs-global

DECLARE @sql nvarchar(max) = 'SELECT * INTO ##tempTable FROM ' 
+ case when @server = '1' THEN 'Server1.' ELSE 'Server2.' END 
+ 'database.dbo.MyTable' 

EXECUTE sp_executesql (@sql) 

SELECT * FROM ##tempTable 
+0

Спасибо! Я не понимал, что глобальные таблицы temp работают так, как это происходит в динамическом SQL. – APH

1

(Благодаря полезным комментатора @XQbert)

Замена ID колонки (Int, Identity) в временную таблицу с колонкой, которая была просто int вызывает

Insert into #tempTable 
    exec(@sql) 

функционировать должным образом.

И что синтаксис и

declare @sql varchar(max) = 'Insert into #tempTable Select * from ' 
+ case when @server = '1' then 'Server1.' else 'Server2.' end 
+ 'database.dbo.MyTable' 

exec(@sql) 

работали, но делаете insert части динамического SQL производятся гораздо более полезными сообщениями об ошибках для устранения неполадок.