Как я могу опустить системные базы данных и позволить заданию агента 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, поскольку ни одна из системных баз данных в любом случае не соответствует вашему соглашению об именах.
Хорошо, я переосмыслил это. Вместо того, чтобы пытаться и затем перехватить ошибку, если она терпит неудачу, как насчет этого нового плана:
- Проверьте, соответствует ли база данных соглашению об именах, которое вы хотите.
- Проверьте, существует ли таблица.
- Создайте таблицу, если это не так, предоставьте разрешения, как и раньше.
- Сделайте вставку.
Надеюсь, это должно сделать это:
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'