Хранимая процедура "For Each Table"

ПУБЛИКАЦИИ  

По материалам статьи Neil Boyle на swynk.com: "For Each Table" Stored Procedure
Перевод Александра Гладченко

Микрософт предлагает для использования с SQL Server очень удобную системную хранимую процедуру по имени sp_msForEachTable. Эта SP предназначена для того, чтобы позволить администратору базы данных исполнять многие простые операции над таблицами с помощью всего одной команды.
В то время как sp_msForEachTable прекрасно работает в большинстве случаев, существует всё же одна проблема: если Вы попытаетесь обслуживать множество владельцев объектов в базе данных, используя синтаксис [владелец].[объект]. Это ещё не было бы большой проблемой, если бы не то, что многие команды (включая 'sp_recompile' и все команды 'DBCC') не могут иметь дело с владельцами; они могут иметь дело только с простым, "старым" именем таблицы.
Учитывая, что многие администраторы баз данных избегают применение множественных владельцев в базе данных (просто, потому, что это лишняя администраторская головная боль) я решил написать версию стандартной процедуры, которая обходится без включения в предложение запроса имени владельца объекта, и привожу полный текст этой процедуры в статье. Написанная мной процедура является, в основном, прямой копией существующей SP (все подтверждения авторских прав MS), только с одной поправкой - я удалил ссылки на владельцев объектов так, что новая процедура будет работать только для таблиц, принадлежащих текущему пользователю. Поскольку объекты наиболее часто принадлежат DBO, а Вы являетесь администратором базы данных, это не должно вызвать проблемы.
Я переименовал сценарий и включил двойной символ подчеркивания в его имя. 'sp_' позволяет мне размещать её в базе данных master и обращаться из контекста любой другой базы, а второй символ подчеркивания позволяет мне легко отличить мой собственный код от стандартного кода MS.

Вот полный код новой SP:

drop proc sp__foreachtable
go

create proc sp__foreachtable

/*** Built from the Microsoft original sp__msForEachTable
**** Use at your own risk
***/

 @command1 nvarchar(2000), @replacechar nchar(1) = N'?',
 @command2 nvarchar(2000) = null,
 @command3 nvarchar(2000) = null,
 @whereand nvarchar(2000) = null,
 @precommand nvarchar(2000) = null,
 @postcommand nvarchar(2000) = null

as
  /* This proc returns one or more rows for each table (optionally,
  matching @where), with each table defaulting to its own result set */
  /* @precommand and @postcommand may be used to force a single
  result set via a temp table. */

  /* Preprocessor won't replace within quotes so have to use str(). */
  declare @mscat nvarchar(12)
  select @mscat = ltrim(str(convert(int, 0x0002)))

  if (@precommand is not null)
      exec(@precommand)

  /* Create the select */

  exec(N'declare hCForEach cursor global for select (object_name(id))
        from dbo.sysobjects o ' + N' where
        OBJECTPROPERTY(o.id, N''IsUserTable'') = 1 ' + N' and
        o.category & ' + @mscat + N' = 0 ' + @whereand)

  declare @retval int
  select @retval = @@error
  if (@retval = 0)
        exec @retval = sp_MSforeach_worker @command1, @replacechar, @command2, @command3

  if (@retval = 0 and @postcommand is not null)
        exec(@postcommand)

  return @retval

Примеры Использования

sp__foreachtable 'dbcc showcontig(?)' /*** SQL 2000 only ***/
sp__foreachtable "dbcc dbreindex(?)"
sp__foreachtable 'sp_recompile ?'

Ограничения использования

Есть ещё множество возможностей для усовершенствования этой процедуры. Предлагаемый Вам сценарий не обрабатывает имена таблиц, которые можно использовать, а также команды, которые ожидают, что им будет передан object_id, а не имя таблицы - именно поэтому пример с DBCC SHOWCONTIG подходит для использования только в SQL 2000.

Примечание к работе ряда хранимых процедур "ForEach"

Ряд хранимых процедур 'ForEach' включает sp_msForEachTable (представленную выше), sp_msForEachDB - которая работает на уровне базы данных, и sp_msForEachWorker - которая является утилитой, называемой "other two".
Когда Вы выполняете команду, используя sp_msForEachTable или sp_msForEachDB, хранимая процедура использует методы динамического SQL, чтобы копировать вашу команду для каждой таблицы или объекта. Эти команды сохранены в курсоре по имени 'hcForEach'. Как только курсор будет построен, вызывается sp_msForEachWorker, которая выбирает и выполняет команды из курсора одну за другой. Если Вы знакомы с динамическим SQL, то можете рассмотреть эти SP, чтобы увидеть что они будут делать.

Дополнительная литература

sp__ForEachTable способна к более сложной работе чем простые примеры, показанные в этой статье. Поскольку она в основном построена на основе аналога SP от Микрософт (sp_msForEachTable), Вы можете читать о её расширенных возможностях в Books Online для получения дополнительной информации. Эта SP была проверена на SQL 7 и SQL 2000.


Перевод: Александра Гладченко  2001г.

ПУБЛИКАЦИИ

Скачать электронную карту Ангарска бесплатно
Сайт управляется системой uCoz