Создание динамики триггера
-
05-09-2019 - |
Вопрос
Я использую MS SQL 2008 и хочу создать триггер в базе данных, которая создается динамически.
Создание базы данных вызывается внутри хранимой процедуры другой базы данных и работает отлично, но когда я хочу добавить триггер или хранимую процедуру, выполнение завершается с ошибкой.
Если я попытаюсь запустить динамический SQL с помощью
EXEC('USE dbase
GO
CREATE TRIGGER [blah]
GO')
Я получил:
Неправильный синтаксис рядом с «GO»
И если я удалю «USE...», триггер будет создан не в той базе данных.
Есть ли способ избежать моих проблем?
Спасибо
Решение
«GO» не является языком T-SQL.Это ключевое слово интерпретируется клиентскими инструментами, такими как SSMS, как разделитель пакетов (что означает «отправить текст на сервер»).
Теперь CREATE TRIGGER должен быть первым оператором в пакете, чтобы нельзя было использовать «USE dbname».
Если вы укажете «USE dbnname» перед EXEC, то оно может оказаться в базе данных по умолчанию для соединения.Вам придется проверить (сейчас не могу, извините)
--Might work
USE dbase
EXEC ('CREATE TRIGGER [blah]
')
Или вам придется использовать sqlcmd или osql для подключения и запуска кода:это позволяет вам установить контекст БД при подключении.Однако не в T-SQL.
Или вы можете попробовать ALTER LOGIN xxx WITh WITh DEFAULT_DATABASE = dbname перед EXEC.
ALTER LOGIN xxx WITH DEFAULT_DATABASE = dbname
--Now the EXEC will connect to default db if above approach fails
EXEC('CREATE TRIGGER [blah]
')
Другие советы
Вы можете переключить базу данных перед вызовом exec и сразу после этого переключиться обратно:
use newdb
exec ('CREATE TRIGGER [blah] ...')
use originaldb
Или создайте связанный сервер с нужной базой данных с включенным RPC и:
EXEC ('CREATE TRIGGER [blah] ...') AT LinkedServerName
Или создайте другого пользователя, у которого есть каталог по умолчанию в базе данных, где вы хотите создать триггер, и:
EXECUTE AS LOGIN = 'UserName'
EXEC ('CREATE TRIGGER [blah] ...')
REVERT
Чтобы создать ссылку, только подтверждающую существование, а затем изменить ее с помощью изменения.
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[MiTrigger]') AND type in (N'TR'))
EXEC ('CREATE TRIGGER [MiTrigger] ON [dbo].[MiTabla] FOR DELETE AS SET NOCOUNT ON')
GO