Я создаю сценарий для автоматического переноса изменений из нескольких баз данных разработки в промежуточную / производственную. По сути, он берет кучу сценариев изменений и объединяет их в один сценарий, заключая каждый сценарий в IF whatever BEGIN ... END
оператор.
Однако для некоторых сценариев требуется GO
оператор, чтобы, например, синтаксический анализатор SQL знал о новом столбце после его создания.
ALTER TABLE dbo.EMPLOYEE
ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
GO -- Necessary, or next line will generate "Unknown column: EMP_IS_ADMIN"
UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
Однако, как только я заключу это в IF
блок:
IF whatever
BEGIN
ALTER TABLE dbo.EMPLOYEE ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
GO
UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
END
Это не удается, потому что я отправляю BEGIN
без соответствия END
. Однако, если я удалю, GO
он снова жалуется на неизвестный столбец.
Есть ли способ создать и обновить один и тот же столбец в одном IF
блоке?
sql
sql-server
tsql
sql-server-2008
BlueRaja - Дэнни Пфлугофт
источник
источник
GO
он должен быть в отдельной строке, поэтому вы можете искать только этот регистр, а не каждое вхождение словаGO
. 2) Вы всегда можете записать, какие операторы были выполнены успешно. Или вы можете обернуть все это в try / catch и использовать свои собственные номера строк, используя некоторую переменную, например @lineNo, которую вы отслеживаете, и сообщать об ошибке. Поскольку вы создаете их автоматически, внесение таких изменений должно быть легким делом. Просто звучит так, будто вы просто не хотите исследовать этот маршрут, хотя я думаю, что есть решения, которые можно найти для всех ваших проблем.Ответы:
У меня была такая же проблема, и мне, наконец, удалось решить ее с помощью SET NOEXEC .
источник
SQLCMD
сценарии режима SS (т. Е. В основном сценарии развертывания), который вызывает (через:r
команду) другие сценарии SS (то есть сценарии дополнительного развертывания) с некоторыми из этих вызовов внутриif
операторов. Ответы Одеда, мелламокба и Энди Джойнера о включении всех этих утверждений вexec
вызовы /begin
- неend
являются стартовыми. Кроме того, методbegin
-end
не будет работать, если есть операторcreate
(например, требует явногоgo
перед ним). Но, чувак, "Святые двойные негативы, Бэтмен!" ;)if
-блок), я бы поставил перед блоком-- If whatever
комментарий, сделал бы отступ и закрепил блок--end If whatever
комментарием.GO
не является SQL - это просто разделитель пакетов, используемый в некоторых инструментах MS SQL.Если вы не используете это, вам необходимо убедиться, что операторы выполняются отдельно - либо в разных пакетах, либо с использованием динамического SQL для населения (спасибо @gbn):
источник
IF
блоке.;
поможет? - Вы только что отредактировали свой ответ: o);
тоже не работает - синтаксический анализатор по-прежнему выдает мне «Неверное имя столбца 'EMP_IS_ADMIN'».Вы можете попробовать
sp_executesql
разделить содержимое каждогоGO
оператора на отдельную строку для выполнения, как показано в примере ниже. Кроме того, существует переменная @statementNo, чтобы отслеживать, какой оператор выполняется, для упрощения отладки, где произошло исключение. Номера строк будут относиться к началу номера соответствующего оператора, вызвавшего ошибку.Вы также можете легко выполнять многострочные операторы, как показано в примере выше, просто заключив их в одинарные кавычки (
'
). Не забывайте экранировать одинарные кавычки внутри строки двойными одинарными кавычками (''
) при создании скриптов.источник
SELECT * <newline> FROM whatever
. Если я выполню каждую строку с ее собственным оператором EXEC, это сломается. Или вы предлагаете мне ломать каждоеGO
заявление?В конечном итоге я заставил его работать, заменив каждый экземпляр в
GO
отдельной строке наЭто намного предпочтительнее, чем заключать каждую группу операторов в строку, но все же далеко от идеала. Если кто-нибудь найдет лучшее решение, опубликуйте его, и я приму его.
источник
IF
блока). Кажется, что в SQL просто нет хорошего способа сделать это.set noexec
Ответ Мины Джейкоб до сих пор является ЕДИНСТВЕННЫМ практическим ответом для использования вSQLCMD
сценарии режима SS (т. Е. В основном сценарии развертывания), который вызывает (через:r
команду) другие сценарии SS (т.е. сценарии дополнительного развертывания) с некоторыми из этих вызовов внутриif
операторов. Ответы Одеда, мелламокба и Энди Джойнера о включении всех этих утверждений вexec
Calls /begin
- неend
являются стартовыми. Кроме того, методbegin
-end
не будет работать, если есть операторcreate
(например, требует явногоgo
перед ним).Вы можете заключить инструкции в BEGIN и END вместо GO между
(Проверено в базе данных Northwind)
Изменить: (Вероятно, протестировано на SQL2012)
источник
set noexec
Ответ Мины Джейкоб до сих пор является ЕДИНСТВЕННЫМ практическим ответом для использования вSQLCMD
сценарии режима SS (т. Е. В основном сценарии развертывания), который вызывает (через:r
команду) другие сценарии SS (т.е. сценарии дополнительного развертывания) с некоторыми из этих вызовов внутриif
операторов. Ответы Одеда, мелламокба и Энди Джойнера о включении всех этих утверждений вexec
Calls /begin
- неend
являются стартовыми. Кроме того, методbegin
-end
не будет работать, если есть операторcreate
(например, требует явногоgo
перед ним).Вы можете попробовать это решение:
источник
Я использовал
RAISERROR
в прошлом для этогоисточник
Вы можете включить операторы
GOTO
и,LABEL
чтобы пропустить код, оставивGO
ключевые слова нетронутыми.источник