2013-09-30 4 views
2

Я пишу сценарий обновления db, который в основном извлекает текущий номер версии из базы данных, а затем создает несколько хранимых процедур, если версия действительна. Если текущая версия не соответствует ожидаемой версии, она должна пропустить выполнение кода.Условно создайте хранимую процедуру с использованием TSQL

Однако я столкнулся с проблемой при написании сценария, потому что CREATE PROCEDURE должен быть первым оператором в пакете, поэтому мне не удается вставить if .. else перед инструкцией процедуры создания.

Я также пытался использовать GOTO, но безрезультатно, потому что GOTO не распространяется на несколько партий. То же самое относится к RETURN и RAISEERROR - остальная часть кода будет выполняться.

Пример сценария:

IF @Version = '1.0' --doesn't work 
BEGIN 
    CREATE PROCEDURE dbo.uspCreateAccount 
    AS BEGIN 
    --The rest of the code goes here 
    END 
END 

Может кто-нибудь пролить некоторый свет на это?

ответ

4

Вы можете выполнить это, используя функциональность exec.

IF @Version = '1.0' 
BEGIN 
    --Drop it if it already exists 
    IF OBJECT_ID('uspCreateAccount', 'P') IS NOT NULL 
     EXEC ('DROP PROCEDURE uspCreateAccount') 
    --Recreate it. 
    EXEC(' 
      CREATE PROCEDURE uspCreateAccount 
      AS BEGIN 
      --The rest of the code goes here 
      END 
    ') 
END 
+0

Кажется, что это хорошо. Попробуем. Благодаря! – user1928346

4

Вы можете использовать exec для запуска команды SQL в новой области. Следующий фрагмент будет запущен, даже если dbo.YourProc уже существует, поскольку в этом случае команда SQL внутри exec() не будет проанализирована.

if not exists (select * from sys.procedures where name = 'YourProc') 
    exec ('create procedure dbo.YourProc as select 1 as a') 
go 
alter procedure dbo.YourProc 
as 
select ... 

Эта конструкция создает пустую процедуру-заглушку, если процедура не существует. Если процедура существует, она запускается alter. Таким образом, он сохраняет права, предоставленные на процедуру.

+0

Извините, но это не совсем то, что я хочу. То, что я прошу, это если версия неправильная, то не создайте процедуру. – user1928346

+0

Проверьте ответ @ cbeckner. Размещение фактического тела внутри 'exec' труднее читать и обслуживать, поэтому я стараюсь избегать этой ситуации, например, проверяя версию в другом вызове базы данных. – Andomar

+0

Да, его решение, похоже, работает. Просто интересно, есть ли там лучшее решение? Поскольку ремонтопригодность становится проблемой, если я использую этот подход. – user1928346

Смежные вопросы