Intereting Posts
Что может вызвать ошибку SQL Server JDBC «Значение не установлено для номера параметра 0» для доступа к выходному параметру? Ошибка «Неверная попытка вызвать« Чтение при закрытии считывателя »» (только для длительных операций) sql server Получите полное имя месяца с даты Как отправить пакет обновлений с операторами одновременно в SQL SQL: поиск самого низкого общего предка иерархии SQL Server 2012 – Лучший способ присвоить увеличивающееся число для разных наборов записей с определенного значения CDC включен, но таблица cdc.dbo <table-name> _CT не заполняется Оптимизация динамических запросов Как вставить несколько операторов select в временную таблицу Переименование всех таблиц в базе данных Просмотры в другой базе данных SQL-запрос не работает. Граф также должен возвращать ноль. Но не работает даже после внешнего соединения Идентификатор чувствительности колонки столбца Doctrine Выделить все теги, которые являются пользователями в вопросах asp.net c # EF Можно ли добавить столбец идентификатора первичного ключа, чтобы решить проблемы взаимоблокировки?

запуск условных операторов DDL на сервере sql

У меня есть ситуация, когда я хочу проверить определенный столбец (например, номер версии), а затем применить кучу ddl-изменений

проблема в том, что я не могу это сделать в блоке IF BEGIN END, так как для операторов DDL требуется разделитель GO между ними, и TSQL этого не позволит.

Мне интересно, есть ли способ сделать это

Solutions Collecting From Web of "запуск условных операторов DDL на сервере sql"

Вам не нужно использовать полный блок. Условие будет выполнять следующий оператор целиком, если вы не используете BEGIN / END – включая один оператор DDL. Это эквивалентно поведению if в Pascal, C и т. Д. Конечно, это означает, что вам придется повторно проверять свое состояние снова и снова. Это также означает, что использование переменных для управления поведением сценария в значительной степени не может быть и речи.

[Edit: CREATE PROCEDURE не работает в приведенном ниже примере, поэтому я изменил его на что-то еще и переместил CREATE PROCEDURE для более расширенного обсуждения ниже]

If ((SELECT Version FROM table WHERE... ) <= 15) CREATE TABLE dbo.MNP ( .... ) GO If ((SELECT Version FROM table WHERE... ) <= 15) ALTER TABLE dbo.T1 ALTER COLUMN Field1 AS CHAR(15) GO ... 

Или что-то в этом роде, в зависимости от вашего состояния.

К сожалению, CREATE / ALTER PROCEDURE и CREATE / ALTER VIEW имеют особые требования, из-за которых сложнее работать. Они в значительной степени обязаны быть единственной вещью в заявлении, поэтому вы не можете комбинировать их с IF вообще.

Для многих сценариев, когда вы хотите «обновить» свои объекты, вы можете работать с ним как условное падение, за которым следует создание:

 IF(EXISTS(SELECT * FROM sys.objects WHERE type='p' AND object_id = OBJECT_ID('dbo.abc'))) DROP PROCEDURE dbo.abc GO CREATE PROCEDURE dbo.abc AS ... GO 

Если вам действительно нужна условная логика, чтобы решить, что делать, тогда единственным способом, который я знаю, является использование EXECUTE для запуска операторов DDL в виде строки.

 If ((SELECT Version FROM table WHERE... ) <= 15) EXECUTE 'CREATE PROC dbo.abc AS .... ') 

Но это очень больно. Вы должны избегать кавычек в теле процедуры, и ее действительно трудно прочитать.

В зависимости от изменений, которые вам нужно применить, вы можете видеть, что все это может стать очень уродливым. Вышеприведенное не включает даже проверку ошибок, которая является королевской болью сама по себе. Вот почему полчища инструментальных мастеров зарабатывают себе на жизнь, выясняя способы автоматизации создания сценариев развертывания.

Сожалею; нет простого «правильного» способа, который работает на все. Это просто то, что TSQL поддерживает очень плохо. Тем не менее, вышеприведенное должно быть хорошим началом.

Несколько заявлений «IF»? Затем вы можете проверить успешность последующих операторов DDL

Динамический SQL? EXEC ('ALTER TABLE foo WITH CHECK ADD CONSTRAINT …')?

Как уже упоминалось, GO является клиентским единственным разделителем пакетов для разбивки единого текстового блока SQL на партии, которые отправляются на SQL Server.

GO распознается клиентскими инструментами, а не сервером. Вы можете иметь CREATE в ваших хранимых процедурах или специальных запросах без GO.