Использование GO в скрипте SSDT после развертывания

Моя база данных SQL Server 2008 R2 развертывается из созданного мной проекта SSDT. Одно странное требование в этом случае — изменить один из столбцов первичного ключа на IDENTITY или наоборот в зависимости от того, где он развернут. Я не в восторге от требования, но это не мой вопрос.

Что я сделал, так это настроил сценарий после развертывания, который должен запускаться условно, в зависимости от того, где происходит развертывание. Все идет нормально.

В моем сценарии я выполняю команду ALTER TABLE ADD, чтобы настроить новый столбец, заполнить его и переименовать в старый столбец. После этого я пытаюсь сделать UPDATE для нового столбца, и он дает сбой, потому что столбец не существует. Я помещаю оператор GO прямо под команду ALTER TABLE ADD, и когда я тестирую сценарий изолированно, это решает проблему, все работает отлично.

-- Add a clone of the ID column with no Identity constraint
ALTER TABLE Communication ADD CommunicationIdNoIdentity INT NOT NULL;
GO
UPDATE Communication
SET CommunicationIdNoIdentity = CommunicationID;

Однако кажется, что это недопустимо в контексте сценария после развертывания. С GO на месте я получаю ошибку сборки прямо здесь:

Ошибка: SQL72007: сбой проверки синтаксиса «Произошел неожиданный конец файла». в партии рядом

Как я могу обойти это? BuildAction в файле установлено значение «Нет», что я считаю правильным.

ОБНОВЛЕНИЕ: хотя ошибка исходит от дочернего скрипта, я, наконец, вернул ее родительскому. Если я сделаю это:

IF @IsDeploymentToDatacenter = 'TRUE'
    :r .\FixIdColumnInCommunicationTable.SQL

оно работает. Если я сделаю это (то, что у меня было изначально), это приведет к ошибкам, которые я описал, среди прочего:

IF @IsDeploymentToDatacenter = 'TRUE'
BEGIN
    :r .\FixIdColumnInCommunicationTable.SQL
END

person Mike K    schedule 03.03.2015    source источник
comment
GO не является оператором или командой SQL. Это разделитель, используемый SQL Server Management Studio, и, следовательно, он недопустим в обычном универсальном SQL. сценарий   -  person marc_s    schedule 04.03.2015
comment
Вы запускаете файл с использованием синтаксиса sqlcmd из основного сценария после развертывания? В противном случае BuildAction должен быть PostDeploy.   -  person db_brad    schedule 04.03.2015
comment
@marc_s это нормально, так как я могу выполнить ALTER, чтобы при запуске UPDATE столбец был там? Без разграничения его с GO.   -  person Mike K    schedule 04.03.2015
comment
@db_brad, у меня есть основной PostDeploy.sql, работающий со строкой :r .\FixCommunication.sql   -  person Mike K    schedule 04.03.2015
comment
Вы должны быть в состоянии делать то, что вы делаете здесь. Я смог вызвать разные команды в дочернем скрипте (скрипт, вызываемый с использованием синтаксиса sql cmd), разделенных GO, и он работал нормально. Возможно, попробуйте поместить свои 2 оператора в 2 отдельных сценария и вызвать их оба из основного сценария после развертывания с помощью операторов SQLCMD.   -  person db_brad    schedule 04.03.2015
comment
Я добавил обновление. У меня это работает, хотя я до сих пор не знаю, почему, правда. Похоже, это как-то связано с помещением его в блок BEGIN...END. Это не нравится. Я могу вытащить его, и он работает. Это не идеально, так как я могу сделать это только с одной строкой, если только я не изменю условие и не сделаю RETURN, но это похоже на хак. Кто-нибудь понимает, что здесь происходит?   -  person Mike K    schedule 04.03.2015
comment
Еще одна странность заключается в том, что если для приведенного выше параметра установлено значение TRUE, он запускается. Если он установлен в FALSE (т.е. скрипт не должен запускаться), то я получаю ошибки от дочернего скрипта.   -  person Mike K    schedule 04.03.2015
comment
Из всего этого я понял, что команда :r в SQLCMD на самом деле больше похожа на макрос. То есть файл, который вы запускаете, буквально расширяется в родительский скрипт. Итак, если вы поместите туда GO, это должно быть хорошо, но если вы окружите вызов :r, скажем, BEGIN...END, это приведет к сбою, потому что GO обрезает BEGIN.   -  person Mike K    schedule 05.03.2015


Ответы (1)


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

Вы должны иметь возможность использовать мой общий или написать его самостоятельно:

person Ed Elliott    schedule 03.03.2015
comment
Я открыт для этого. Я решил, что мои параметры были помещены в сценарий таблицы, а затем удалены после развертывания (это подход, который я выбрал); или не помещайте его в сценарий таблицы, а затем ДОБАВЬТЕ его после развертывания. Если я помещу его в сценарий таблицы, как вы предлагаете, как я смогу остановить его развертывание? - person Mike K; 04.03.2015
comment
Привет, Майк. Я дважды проверил, и вы не можете назвать личность, поэтому использование участника развертывания в этом случае не сработает. Раньше я обходил подобные проблемы, заключая каждый из двух сценариев в отдельные вызовы sp_execute_sql — это не очень красиво, но означает, что они оцениваются и выполняются в два этапа (вероятно, вы можете просто поместить вторую часть в вызов sp_execute_sql) - person Ed Elliott; 04.03.2015