Неожиданное поведение sp_MSforeachdb

#sql-server #sql-server-2008 #sql-server-2008-r2 #truncate #sp-msforeachdb

#sql-сервер #sql-server-2008 #sql-server-2008-r2 #усечение #sp-msforeachdb

Вопрос:

Я работаю над улучшением своего понимания некоторых системных sprocs, и я очень смущен этим скриптом, над которым я работал. Чтобы проверить свое понимание sp_MSForEachDB , я решил написать скрипт, который будет усекать журналы всех баз данных на сервере. Таким образом, я придумал следующий сценарий:

 sp_MSForEachDb 'IF LOWER(rtrim(''?'')) NOT IN ('''', ''master'', ''tempdb'', ''tempdev'', ''model'', ''msdb'')
                BEGIN
                    declare @LogFile nvarchar(max)
                    USE [?]
                    SELECT @LogFile = sys.sysaltfiles.name FROM sys.sysdatabases
                    INNER JOIN sys.sysaltfiles ON sys.sysdatabases.dbid = sys.sysaltfiles.dbid
                    WHERE (sys.sysaltfiles.fileid = 1) AND (sys.sysdatabases.name = ''?'')
                    print ''DB: [?], Log: ''   @LogFile
                    CHECKPOINT
                    DBCC SHRINKFILE (@LogFile, 1)
                END'
  

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

Однако в инструкции print выводится ИМЕННО то, что я ожидал от нее напечатать. Однако, если я вручную просто введу функциональную часть этого скрипта для каждой базы данных:

 USE [Seed]
CHECKPOINT
DBCC SHRINKFILE('Seedlog', 1)
  

это работает в 100% случаев.

Почему мой sp_MSForEachDB «цикл» работает не так, как ожидалось? Чего я не понимаю?

Ответ №1:

Похоже, что ваш запрос возвращает логическое имя файла данных, а не файла журнала? (fileID=1)

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

1. Ух ты, какая оплошность. Хороший улов! Спасибо за ваши замечания. 🙂