Как я могу опустить системные базы данных и позволить заданию агента SQL Server 2008 переместиться за ERROR_NUMBER 208?

Я создал задание агента SQL Server 2008, которое работает со всеми базами данных на сервере. Я использую недокументированную процедуру MS, sp_MSforEachDB, Я указываю только определенные базы данных для обработки, и когда эти базы данных будут найдены, если ERROR_NUMBER = 208Я хочу, чтобы таблица была создана и обработка продолжалась до следующей базы данных. Я также хочу опустить системные базы данных, чтобы таблица не создавалась в системной базе данных. Хотя, указав имена баз данных, которые я хочу обработать, я мог бы создать таблицу, в которой не было ни одной. Код, который я показываю ниже, работает, если 'focus' установлен для конкретной базы данных. Кроме того, когда я запускаю его, я получаю таблицу, созданную в базе данных master, что я не хочу делать. Что я пытаюсь сделать с помощью кода, который я создал: 1. выбрать все базы данных на сервере SQL с именем, например "xyz_%" 2. если существует таблица "SESSIONS", удалить все записи старше 5 минут 3. если Таблица "СЕССИИ" не существует, затем создайте ее и продолжите обработку - вот где я получаю 208 error - invalid object because this table does not existКогда задание видит, что нет таблицы Sessions, задание останавливается и другие базы данных не обрабатываются. Мне нужно, чтобы все названные базы данных в 1 были обработаны. Если таблица SESSIONS отсутствует, я получаю ошибку 208, которая говорит: "Неверное имя объекта" master.SchemaName.sessions ". Если я установлю" фокус "на базу данных без таблицы сессий, мой код запустится, и таблицы будут созданы но я все еще получаю ошибку 208. - Неверное имя объекта "master.SchemaName.sessions". Другие ошибки не отображаются.

Если бы кто-то мог посмотреть на мой код, чтобы увидеть, где моя проблема, это было бы здорово.

Я подтвердил, что получаю ошибку 208, используя приведенную ниже пробную версию. Я также получаю сообщение об ошибке 2760 во втором Try Catch, в котором говорится, что указанная схема не существует или у меня нет доступа. Я администратор на этом сервере.

Я использую SQL в течение нескольких лет, и я не считаю себя экспертом. Я исследовал это в Google, чтобы придумать код, который у меня есть ниже. Любая помощь будет оценена.

declare @ERROR INT

BEGIN TRY

exec sp_MSforeachdb 'IF "[?]" NOT IN ("master", "model","msdb", "tempdb")
BEGIN
 DELETE FROM [?].schema.sessions WHERE name like ''xyz_%''
 AND sessionStart <DATEADD(mi, -5,GETDATE())
END'                  

END TRY

BEGIN CATCH
SELECT  ERROR_NUMBER() AS error_number,  ERROR_MESSAGE() AS error_message
    SELECT @ERROR = ERROR_NUMBER()
    If @ERROR = 208
    BEGIN TRY
     /* create the Sessions table */
     BEGIN
     CREATE TABLE  [SCHEMA].[SESSIONS](
       [authuser] [varchar](30) NULL,
       [sessionID] [char](36) NULL,
       [sessionStart] [datetime] NULL)

grant select,delete on reviewadmin.sessions to public;
     END
    END TRY  
 BEGIN CATCH 
  SELECT  ERROR_NUMBER() AS error_number,  ERROR_MESSAGE() AS error_message
 END CATCH 
 END CATCH

1 ответ

Вы можете попробовать использовать DB_ID() Я верю DB_ID() всегда 1-4 (если у вас нет базы данных для распространения). Теоретически, просто проверьте, больше ли DB_ID() чем 4:

exec sp_MSforeachdb 'IF DB_ID(''?'')) > 4
BEGIN
 DELETE FROM [?].schema.sessions WHERE name like ''xyz_%''
 AND sessionStart <DATEADD(mi, -5,GETDATE())
END' 

Кроме того, не похоже, что вы используете правильную базу данных в обработчике ошибок - конечно, ваш try try, который создает таблицу, должен быть в вызове sp_MSforeachdb также?

Я имею в виду, что в вашем тексте вы запускаете для каждой базы данных, в том числе это в try catch:

CREATE TABLE [?].[SCHEMA].[SESSIONS]
(
   [authuser]     [VARCHAR](30) NULL,
   [sessionID]    [CHAR](36) NULL,
   [sessionStart] [DATETIME] NULL
)

Еще одна вещь - в данный момент вы, кажется, жестко закодировали значение reviewadmin.sessions в вашем коде предоставления разрешения - я предполагаю, что вы имели в виду, что быть вашим новым [?].[Schema].[Sessions] таблица - опять же, что должно быть в вызове sp_MSforeachdb поэтому он знает, на какой базе данных работать.

Я надеюсь, что дал вам достаточно для продолжения, я не на машине, где я могу написать и протестировать все это, я боюсь!


Если вы просто хотите базы данных с именем xyz_%:

exec sp_MSforeachdb 'IF DB_NAME() LIKE ''xyz_%''
BEGIN
 DELETE FROM [?].schema.sessions WHERE name like ''xyz_%''
 AND sessionStart <DATEADD(mi, -5,GETDATE())
END'

Обратите внимание, что теперь мы можем пропустить проверку для DB_ID > 4, поскольку ни одна из системных баз данных в любом случае не соответствует вашему соглашению об именах.


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

  1. Проверьте, соответствует ли база данных соглашению об именах, которое вы хотите.
  2. Проверьте, существует ли таблица.
  3. Создайте таблицу, если это не так, предоставьте разрешения, как и раньше.
  4. Сделайте вставку.

Надеюсь, это должно сделать это:

EXEC Sp_msforeachdb 'IF ''?'' LIKE ''xyz_%''
                    BEGIN
                        IF OBJECT_ID(''?.REVIEWADMIN.Sessions'', ''U'') IS NULL
                        BEGIN
                            CREATE TABLE [?].ReviewAdmin.Sessions
                            (
                                [authuser]     [VARCHAR](30) NULL,
                                [sessionID]    [CHAR](36) NULL,
                                [sessionStart] [DATETIME] NULL
                            )

                            grant select,delete on reviewadmin.sessions to public;

                        END

                        DELETE FROM [?].ReviewAdmin.Sessions
                        WHERE sessionStart < DATEADD(mi, -5,GETDATE())

                    END'
Другие вопросы по тегам