запуск условных операторов DDL на сервере sql - PullRequest
8 голосов
/ 07 апреля 2009

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

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

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

Ответы [ 3 ]

6 голосов
/ 07 апреля 2009

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

[Редактировать: 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 поддерживает очень плохо. Тем не менее, вышесказанное должно быть хорошим началом.

1 голос
/ 07 апреля 2009

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

Динамический SQL? EXEC ('ALTER TABLE foo с проверкой и ограничением ...')?

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

1 голос
/ 07 апреля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...