Подтвердить что ты не робот

Условная логика в PostDeployment.sql script с использованием SQLCMD

Я использую проект базы данных SQL 2008 (в visual studio) для управления схемой и исходными тестовыми данными для моего проекта. Проект atabase использует пост-развертывание, которое включает в себя ряд других скриптов с использованием синтаксиса SQL: ". R".

Я хотел бы иметь возможность условно включать определенные файлы на основе переменной SQLCMD. Это позволит мне запускать проект несколько раз с нашей ночной сборкой для настройки различной версии базы данных с различными конфигурациями данных (для многопользовательской системы).

Я пробовал следующее:

IF ('$(ConfigSetting)' = 'Configuration1')
  BEGIN
    print 'inserting specific configuration' 
:r .\Configuration1\Data.sql
  END
ELSE
  BEGIN
    print 'inserting generic data' 
:r .\GenericConfiguration\Data.sql
  END

Но я получаю ошибку компиляции: SQL01260: произошла ошибка фатального парсера: Script.PostDeployment.sql

Кто-нибудь видел эту ошибку или сумел настроить их postdeployment script, чтобы быть гибким таким образом? Или я об этом совершенно не согласен?

Спасибо, Rob

P.S. Я также попытался изменить это так, чтобы путь к файлу был переменным, похожим на этот пост. Но это дает мне ошибку, говоря, что путь неверный.

4b9b3361

Ответ 1

UPDATE

Теперь я обнаружил, что синтаксис if/else выше не работает для меня, потому что некоторые из моих связанных скриптов требуют инструкции GO. По существу: r просто импортирует скрипты inline, поэтому это становится недопустимым sytax.

Если вам нужен оператор GO в связанных сценариях (как и я), тогда нет никакого простого способа обойти это, я закончил создание нескольких сценариев пост-развертывания, а затем изменил свой проект, чтобы перезаписать основной пост-отказ script во время сборки в зависимости от конфигурации сборки. Это сейчас делает то, что мне нужно, но похоже, что должен быть более простой способ!

Для тех, кому нужно одно и то же - Я нашел это сообщение полезным

Итак, в моем проекте у меня есть следующие файлы для развертывания после публикации:

  • Script.PostDeployment.sql(пустой файл, который будет заменен)
  • Default.Script.PostDeployment.sql(ссылки на скрипты, необходимые для конфигурации стандартных данных)
  • Configuration1.Script.PostDeployment.sql(ссылки на скрипты, необходимые для конкретной конфигурации данных)

Затем я добавил следующее в конец файла проекта (щелкните правой кнопкой мыши, чтобы выгрузить, а затем щелкните правой кнопкой мыши):

  <Target Name="BeforeBuild">
      <Message Text="Copy files task running for configuration: $(Configuration)" Importance="high" />
      <Copy Condition=" '$(Configuration)' == 'Release' " SourceFiles="Scripts\Post-Deployment\Default.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
      <Copy Condition=" '$(Configuration)' == 'Debug' " SourceFiles="Scripts\Post-Deployment\Default.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
      <Copy Condition=" '$(Configuration)' == 'Configuration1' " SourceFiles="Scripts\Post-Deployment\Configuration1.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
  </Target>

Наконец, вам нужно будет настроить соответствующие конфигурации сборки в решении.

Кроме того, для тех, кто пробовал другие работы, я также пробовал следующее без везения:

  • Создание события post build для копирования файлов вместо того, чтобы взломать файл проекта XML. я не мог заставить это работать, потому что я не мог сформировать правильный путь к файлу post-развертывания script. Эта проблема с подключением описывает проблему

  • Использование переменных для пути script для перехода к команде: r. Но при таком подходе я столкнулся с несколькими ошибками.

Ответ 2

Вот как я обрабатываю условное развертывание в процессе после развертывания для развертывания тестовых данных для конфигурации Debug, но не Release.

Сначала в проводнике решений откройте папку свойств проекта и щелкните правой кнопкой мыши, чтобы добавить новый файл SqlCmd.variables.

Назовите файл Debug.sqlcmdvars.

Внутри файла добавьте свои пользовательские переменные, а затем добавьте конечную переменную с именем $(BuildConfiguration) и установите значение Debug.

Повторите этот процесс, чтобы создать Release.sqlcmdvars, установив $(BuildConfiguration) для выпуска.

Теперь настройте свои конфигурации: Откройте страницу свойств проекта на вкладке "Развернуть". В верхнем раскрывающемся списке настройте конфигурацию как Debug. В нижнем раскрывающемся списке (переменные команды Sql) задайте файл в Properties\Debug.sqlcmdvars.

Повторить для выпуска как: В верхней раскрывающемся списке установите конфигурацию для выпуска. В нижнем раскрывающемся списке (переменные команды Sql) установите файл в Properties\Release.sqlcmdvars.

Теперь, в вашем файле Script.PostDeployment.sql, вы можете указать условную логику, например:

IF 'Debug' = '$(BuildConfiguration)'
BEGIN
PRINT '***** Creating Test Data for Debug configuration *****';
:r .\TestData\TestData.sql
END

В проводнике решений щелкните правой кнопкой мыши по решению верхнего уровня и откройте Configuration Manager. Вы можете указать, какая конфигурация активна для вашей сборки. Вы также можете указать конфигурацию в командной строке MSBUILD.EXE.

Теперь вы можете: теперь ваши сборки разработчика содержат тестовые данные, но не вашу сборку релизов!

Ответ 3

Мне удалось решить проблему с помощью метода noexec.

Итак, вместо этого:

IF ('$(ConfigSetting)' = 'Configuration1')
 BEGIN
    print 'inserting specific configuration' 
    :r .\Configuration1\Data.sql
 END

Я отменил условие и установил NOEXEC ON, чтобы пропустить импортированный оператор (ы):

IF ('$(ConfigSetting)' <> 'Configuration1')
    SET NOEXEC ON

:r .\Configuration1\Data.sql

SET NOEXEC OFF

Убедитесь, что вы отменили его, если вы хотите выполнить любые последующие утверждения.

Ответ 4

Как выяснил Роб, инструкции GO не разрешены в связанных скриптах SQL, так как это может вложить его в инструкции BEGIN/END.

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

IF '$(DeployTestData)' = 'True'
BEGIN
    :r .\TestData\Data.sql
END
GO -- moved from Data.sql

Обратите внимание, что я также создал новую переменную в моем файле sqlcmdvars с именем $(DeployTestData), который позволяет мне включать/отключать тестирование script.

Ответ 5

Я нашел взломать блог MSDN, который работал достаточно хорошо. Хитрость заключается в том, чтобы написать команды в файл temp script, а затем выполнить это script. В основном эквивалент динамического SQL для SQLCMD.

-- Helper newline variable
:setvar CRLF "CHAR(13) + CHAR(10)"
GO
-- Redirect output to the TempScript.sql file
:OUT $(TEMP)\TempScript.sql

IF ('$(ConfigSetting)' = 'Configuration1')
  BEGIN
    PRINT 'print ''inserting specific configuration'';' + $(CRLF)   
    PRINT ':r .\Configuration1\Data.sql' + $(CRLF)
  END
ELSE
  BEGIN
    PRINT 'print ''inserting generic data'';' + $(CRLF) 
    PRINT ':r .\GenericConfiguration\Data.sql' + $(CRLF)
  END
GO
-- Change output to stdout
:OUT stdout

-- Now execute the generated script
:r $(TEMP)\TempScript.sql
GO

Затем файл TempScript.sql будет содержать:

print 'inserting specific configuration';   
:r .\Configuration1\Data.sql

или

print 'inserting generic data';
:r .\GenericConfiguration\Data.sql

в зависимости от значения $(ConfigSetting) и при выполнении команд GO и т.д. проблем не будет.

Ответ 6

Я был вдохновлен решением Роба Берда. Тем не менее, я просто использую Build Events для замены сценариев пост-развертывания на основе выбранной конфигурации сборки.

  • У меня есть одно пустое развертывание "dummy" post script.
  • Я установил событие pre-build для замены этого файла "dummy" на основе выбранной конфигурации сборки (см. прикрепленное изображение).
  • Я установил событие post-build для размещения файла "dummy" после завершения сборки (см. прикрепленное изображение). Причина в том, что я не хочу создавать изменения в управлении изменениями после сборки.

Build Events setup example