Разделение нескольких операторов SQL Server, работающих в пакетном режиме
Я пытаюсь отправить партию CREATE TRIGGER
операторы как строка для обработки при переносе моей БД
CREATE TRIGGER [dbo].[triggerBar] ON [dbo].[tableBar]
INSTEAD OF UPDATE,INSERT AS
BEGIN
SET NOCOUNT ON
-- Trigger body here..
END;
CREATE TRIGGER [dbo].[triggerFoo] ON [dbo].[tableFoo]
INSTEAD OF UPDATE,INSERT AS
BEGIN
SET NOCOUNT ON
-- Trigger body here..
END;
Поэтому я разграничиваю каждый блок операторов ;
но я все еще получаю эту ошибку:
Неверный синтаксис рядом с ключевым словом "TRIGGER"
При отправке только 1-й триггер работает просто отлично. Не уверен, что не так.
3 ответа
Согласно документации на партии вы не можете поставить несколько CREATE TRIGGER
заявления в той же партии:
Операторы CREATE DEFAULT, CREATE FUNCTION, CREATE PROCEDURE, CREATE RULE, CREATE SCHEMA, CREATE TRIGGER и CREATE VIEW нельзя объединять с другими операторами в пакете. Оператор CREATE должен запустить пакет. Все остальные операторы, которые следуют в этом пакете, будут интерпретироваться как часть определения первого оператора CREATE.
GO
работает, потому что это пакетный разделитель, распознаваемый SSMS, sqlcmd и средствами разработки SQL Server, который никогда не отправляется на сервер. Инструмент использует его для разделения текста на пакеты и отправки их по одному на сервер. Транзакции работают между пакетами (в конце концов, это одно и то же соединение), поэтому можно выполнить откат определенных операторов DDL.
Я предполагаю, что вы хотите создать и выполнить скрипт создания базы данных из Node.
Одно из решений состоит в том же подходе, что и инструменты SQL Server: генерировать отдельные пакеты и выполнять их один за другим для базы данных.
Другой вариант - создать один сценарий SQL с GO
разделители и выполнить его с помощью инструментов командной строки SQL Server. Это более удобно, потому что вы можете сохранять и создавать версии скрипта, обнаруживать изменения и т. Д.
Третий вариант - использовать средства разработки SQL Server для моделирования вашей базы данных. Проекты базы данных поддерживают управление версиями и проверку. Основное преимущество заключается в том, что SSDT может генерировать сценарий для обновления целевой базы данных, аналогично тому, что делают инструменты Redgate. SSDT достаточно умен и может распознавать переименования и т. Д., Которые выполняются внутри самого инструмента, и использовать, например, sp_rename
вместо удаления одного столбца и создания нового.
Еще одним преимуществом является то, что SSDT генерирует dacpac
по сути скомпилированная модель, которая может использоваться для сравнения с целевой базой данных и генерации скрипта обновления.
Это значительно облегчает непрерывное развертывание базы данных. Поддерживается AppVeyor, TFS. TeamCity и любой инструмент / сервис, который может запустить инструмент sqlpackage.
Недостатком является то, что SSDT работает только для баз данных SQL Server.
Некоторые заявления не могут иметь ничего перед ними. В этом случае в рамках SSMS используйте GO
для указания конца пакета (это эффективно очищает буферы, поэтому любые переменные, объявленные до GO
будут стерты).
Если вы находитесь в SSMS, вы можете:
CREATE TRIGGER ... AS ...
GO
CREATE TRIGGER ... etc
Если вы находитесь за пределами SSMS, вы должны либо отправить отдельные команды, либо поместить их в строку в T-SQL и выполнить строку:
DECLARE @Trig1 NVARCHAR(MAX)
DECLARE @Trig2 NVARCHAR(MAX)
DECLARE @Trig3 NVARCHAR(MAX)
SET @Trig1 = 'CREATE TRIGGER ...'
SET @Trig2 = 'CREATE TRIGGER ...'
SET @Trig3 = 'CREATE TRIGGER ...'
EXEC (@Trig1)
EXEC (@Trig2)
EXEC (@Trig3)
Для тех, кто хочет сделать это-
GO
не всегда является хорошим решением для запуска нескольких пакетов, потому что это не T-SQL, его понимает только SSMS и некоторые инструменты командной строки. Например, вы не можете использовать его в хранимой процедуре или функции.
Означает ли это, что хранимые процедуры и функции ограничены одним пакетом?
Об этом редко говорят, если не считать шепота в конференц-залах, но на самом деле вы можете запускать несколько пакетов в одном скрипте T-SQL, который гарантированно будет работать где угодно. Динамический SQL.
EXEC sp_executesql @sql
всегда выполняется в пределах своего пакета. Кроме того, вы можете окружить несколько
EXEC sp_executesql
звонки с транзакцией, если вам нужно. Динамический SQL очень сложно писать, но он позволяет вам делать такие вещи, как несколько пакетов в sproc, что в противном случае было бы невозможно.