Помощь по sp_msforeachdb-подобным запросам - PullRequest
1 голос
/ 04 февраля 2009

Где я нахожусь, у нас есть пакет программного обеспечения, работающий в системе мейнфрейма Мэйнфрейм создает ночной дамп на сервер SQL, так что каждый из наших клиентов имеет свою собственную базу данных на сервере. В экземпляре сервера также есть несколько других баз данных, плюс несколько старых клиентских БД без данных.

Нам часто нужно запускать отчеты или проверять данные по всем клиентам. Я хотел бы иметь возможность запускать запросы, используя sp_msforeachdb или что-то подобное, но я не уверен, как я могу отфильтровать нежелательные БД из списка. Есть мысли о том, как это может работать?

Мы все еще находимся на SQL Server 2000, но должны перейти на 2005 через несколько месяцев.


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

Что я хочу сделать, это сделать так, чтобы программисты, работающие над запросами для использования в своих программах, могли легко написать запрос с использованием одной клиентской базы данных, а затем практически мгновенно запустить (тестировать) код, разработанный и построенный на базе данных одного клиента. на всех 50 или около того клиентских БД, практически без изменений.

Имея это в виду, вот мой код, который в настоящее время находится в Management Studio (частично запутанный):

use [master]
declare @sql varchar(3900) 

set @sql = 'complicated sql command added here'

-----------------------------------
declare @cmd1 varchar(100)
declare @cmd2 varchar(4000)
declare @cmd3 varchar(100)
set @cmd1 = 'if ''?'' like ''commonprefix_%'' raiserror (''Starting ?'', 0, 1) with nowait'
set @cmd3 = 'if ''?'' like ''commonprefix_%'' print ''Finished ?'''
set @cmd2 = 
    replace('if ''?'' like ''commonprefix_%'' 
    begin 
        use [?]
        {0} 
    end', '{0}', @sql)

exec sp_msforeachdb @command1 = @cmd1, @command2 = @cmd2, @command3 = @cmd3

Хорошая вещь в этом - все, что вам нужно сделать, это установить переменную @sql в текст вашего запроса. Очень легко превратить в хранимую процедуру. Это динамический sql, но опять же: он используется только для разработки (известные последние слова;)). Недостатком является то, что вам все еще нужно избегать одинарных кавычек, используемых в запросе, и большую часть времени вы будете добавлять дополнительный столбец ''?'' As ClientDB в список выбора, но в остальном он работает достаточно хорошо.

Если сегодня у меня нет другой действительно хорошей идеи, я хочу превратить ее в хранимую процедуру, а также собрать версию в виде табличной функции, используя временную таблицу, чтобы поместить все результаты в один набор результатов (только для запросов на выборку) .

Ответы [ 4 ]

1 голос
/ 04 февраля 2009

Просто оберните оператор, который вы хотите выполнить в IF NOT IN:

EXEC    sp_msforeachdb  "
IF      '?'     NOT IN ('DBs','to','exclude')   BEGIN
        EXEC    sp_whatever_you_want_to
END
"
0 голосов
/ 04 февраля 2009

Подобные вещи довольно просты в пакетах служб SSIS 2005 года. Возможно, вы могли бы создать экземпляр где-нибудь на сервере.

У нас настроено несколько серверов, поэтому у нас есть таблица, которая указывает, какие серверы будут опрашиваться. Затем мы извлекаем, среди прочего, список всех баз данных. Используется для скриптов резервного копирования.

Вы можете сохранить этот список баз данных и добавить несколько полей для своих собственных целей. У вас может быть другой пакет или шаг, в зависимости от того, как вы решите, о каких базах данных следует составлять отчеты, и можно ли это сделать программно.

Вы можете получить код здесь бесплатно: http://www.sqlmag.com/Articles/ArticleID/97840/97840.html?Ad=1

Мы основали нашу систему на этом коде.

0 голосов
/ 04 февраля 2009

Как насчет определения sp_msforeachdb и его подстройки под ваши цели? Чтобы получить определение, вы можете запустить его (сначала нажмите Ctrl-T, чтобы перевести панель результатов в текстовый режим):

sp_helptext sp_msforeachdb

Очевидно, что вы захотите создать собственную версию этого sproc, а не перезаписывать оригинал; o)

0 голосов
/ 04 февраля 2009

Каждый из наших серверов баз данных содержит базу данных «DBA», которая содержит таблицы, полные метаданных, подобных этой.

Таблица «Базы данных» будет содержать список всех баз данных на сервере, и вы можете поставить флажки в столбцах, чтобы указать состояние базы данных (в режиме реального времени, архив, система и т. Д.).

Тогда первое, что делает ваш SCRIPT, это заходит в вашу базу данных DBA, чтобы получить список всех баз данных, с которыми он должен работать.

У нас даже есть скрипт ночного обслуживания, который проверяет, что все базы данных физически на сервере также внесены в нашу таблицу «DBA.databases», и предупреждает нас, если это не так. (Поскольку добавление строки в эту таблицу должно выполняться вручную)

...