Вопрос

Я использую 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top