Ну, вот как это сделать, используя cursor
:
use database
go
declare @link_table nvarchar(255)
declare @local_table nvarchar(255)
declare table_list cursor for
select
tlink.name,
tlocal.name
from
linkedserver.database.sys.tables tlink
left outer join sys.tables tlocal on
tlink.name = tlocal.name
open table_list
fetch next from table_list into @link_table, @local_table
while @@FETCH_STATUS = 0
begin
begin try
if @local_table is not null
begin
sp_executesql N'drop table ' + quotename(@local_table)
end
sp_executesql N'select * into ' + quotename(@link_table) +
' from linkedserver.database..' + quotename(@link_table)
print @link_table + ' copied.'
end try
begin catch
print 'Error: ' + ERROR_MESSAGE()
end catch
fetch next from table_list into @link_table, @local_table
end
close table_list
deallocate table_list
Хотя обычно следует избегать курсоров, здесь вы собираетесь использовать много логики для каждой строки. Итак, вот оно. Он захватывает все связанные таблицы и сопоставляет с ними любые локальные таблицы, или null
, если локальная таблица не существует. Это помещает его в cursor
, который мы можем использовать для перебора набора строк.
Команда fetch next
берет следующую строку из нашего cursor
и затем применяет к ней вашу логику (drop
если локальная таблица существует, тогда выполните select * into...
).
Вы можете отловить ошибки одним из двух способов. Я использовал блок try...catch
, но вы также можете проверить @@ERROR
и посмотреть, не равен ли он нулю. На самом деле, с чем вам удобнее всего.
В качестве заявления об отказе от толпы против курсора: курсоры не являются злом, они просто часто используются ненадлежащим образом.