Microsoft SQL: абстрактный скрипт для нескольких баз данных

#sql-server-2005 #tsql #sql-server-2008

#sql-server-2005 #tsql #sql-server-2008

Вопрос:

Мне нужно реплицировать записи каталога изображений с одного сервера на другой, имена баз данных которых начинаются с p_ Я могу жестко запрограммировать это следующим образом (одно из многих утверждений):

 delete
from      p_PhotoDB.dbo.item_keyword
where     not exists (
    select  null as nothing
    from    OtherServer.p_PhotoDB.dbo.item_keyword new
    where   p_PhotoDB.dbo.item_keyword.item_id = new.item_id and
            p_PhotoDB.dbo.item_keyword.keyword_id = new.keyword_id
)
  

Я знаю, что мог бы поместить все это в строковую переменную и exec (@variable) , но это будет компилироваться каждый раз для каждого оператора для каждого каталога …

Есть ли способ изменить p_PhotoDB ссылку для каждой найденной базы данных, начинающейся с p_ , без использования какой-либо формы exec (@variable) ?

Комментарии:

1. Что вы подразумеваете под «компиляцией»? Вы тестировали использование динамического SQL для этого? Была ли проблема с производительностью (или другая), которую вы конкретно видели, или вы просто предполагаете, что она будет?

2. Я написал его с помощью exec ( @variable), который включает пользовательский ввод, поэтому возможен ввод, но для запуска требуется около минуты, даже если ему нечего делать. Просто интересно, есть ли хороший трюк или что-то, что я мог бы сделать, чтобы ссылаться на набор имен баз данных в этих запросах.

Ответ №1:

Доктор Зим.,

Насколько мне известно, это невозможно сделать на уровне базы данных.

Конечно, существуют инструменты, которые могут помочь вам в этом, такие как Redgate Compare или встроенные в различные версии Visual Studio.

Если вам нужен способ автоматизировать это в периодически запускаемом скрипте, вы могли бы использовать СИНОНИМЫ для таблиц, но там определенно требуется некоторая предварительная работа, и это определенно не полезно в ряде ситуаций. СМОТРИТЕ: http://msdn.microsoft.com/en-us/library/ms177544.aspx

Я надеюсь, что это поможет.

Ответ №2:

Вместо использования exec(@variable) используйте exec sp_ExecuteSQL . Он создает один план выполнения в отличие от нового для каждого выполнения. Смотрите статью MSDN «Использование sp_ExecuteSQL». Затем вы можете использовать динамический SQL для изменения имени базы данных или использовать цикл для перебора набора баз данных. В полу-псевдокоде:

 Set @DbList='p_db1,p_db2,p_db3,...'

--- Loop through comma separated list and build dynamic sql
-- while
set @SQL='delete
from      ' @CurrentDBName '.dbo.item_keyword
where     not exists (
    select  null as nothing
    from    OtherServer.p_PhotoDB.dbo.item_keyword new
    where   ' @CurrentDBName '.dbo.item_keyword.item_id = new.item_id and
            ' @CurrentDBName '.dbo.item_keyword.keyword_id = new.keyword_id
)'

-- end while
exec sp_ExecuteSQL @SQL,N''