Как определить, существует ли хранимая процедура - PullRequest
118 голосов
/ 02 июня 2009

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

Как я могу сделать это в sql.

Я использую SQL Server 2005

Ответы [ 11 ]

152 голосов
/ 02 июня 2009

Если вы СОБИРАЕТЕ и СОЗДАЕТЕ процедуру, вы потеряете настройки безопасности. Это может раздражать вашего администратора базы данных или вообще сломать ваше приложение.

Что я делаю, это создаю тривиальную хранимую процедуру, если она еще не существует. После этого вы можете изменить хранимую процедуру по своему вкусу.

IF object_id('YourSp') IS NULL
    EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...

Таким образом, настройки безопасности, комментарии и другие метаданные будут действовать после развертывания.

139 голосов
/ 02 июня 2009

Самый чистый способ - проверить его существование, отбросить его, если он существует, а затем воссоздать его. Вы не можете встроить оператор "create proc" в оператор IF. Это должно сделать красиво:

IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO

CREATE PROC MySproc
AS
BEGIN
    ...
END
30 голосов
/ 02 июня 2009

Если вы имеете дело только с хранимыми процедурами, самое простое, что вы можете сделать - это, вероятно, удалить процедуру, а затем воссоздать ее. Вы можете сгенерировать весь код для этого с помощью мастера создания сценариев в SQL Server.

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[YourSproc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[YourSproc]

CREATE PROCEDURE YourSproc...
15 голосов
/ 22 ноября 2015

С SQL Server 2016 CTP3 вы можете использовать новые DIE операторы вместо больших IF оболочек

Синтаксис:

DROP {PROC | ПРОЦЕДУРА} [ЕСЛИ СУЩЕСТВУЕТ] {[имя_схемы. ] процедура } [, ... n]

Запрос:

DROP PROCEDURE IF EXISTS usp_name

Подробнее здесь

10 голосов
/ 02 июня 2009
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xxx]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
BEGIN
CREATE PROCEDURE dbo.xxx

где xxx - имя процесса

3 голосов
/ 02 июня 2009

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

2 голосов
/ 02 июня 2009
IF OBJECT_ID('SPNAME') IS NULL
     -- Does Not Exists
ELSE
     -- Exists
1 голос
/ 09 апреля 2019

Вы можете написать запрос следующим образом:

IF OBJECT_ID('ProcedureName','P') IS NOT NULL
    DROP PROC ProcedureName
GO

CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....

Более подробно о приведенном выше синтаксисе:
OBJECT_ID - это уникальный идентификационный номер для объекта в базе данных, он используется внутри SQL Server. Так как мы передаем имя_процесса , за которым следует тип объекта P , который сообщает SQL Server, что вы должны найти объект с именем имя_процесса , имеющий тип то есть P

Этот запрос найдет процедуру и, если она будет доступна, отбросит ее и создаст новую.

Для получения подробной информации о OBJECT_ID и типах объектов, пожалуйста, посетите: SYS.Objects

0 голосов
/ 18 августа 2017

Приведенный ниже код проверит, существует ли хранимая процедура или нет.

Если он существует, он изменится, если он не существует, он создаст для вас новую хранимую процедуру:

//syntax for Create and Alter Proc 
DECLARE @Create NVARCHAR(200) = 'Create PROCEDURE sp_cp_test'; 
DECLARE @Alter NVARCHAR(200) ='Alter PROCEDURE sp_cp_test'; 
//Actual Procedure 
DECLARE @Proc NVARCHAR(200)= ' AS BEGIN select ''sh'' END'; 
//Checking For Sp
IF EXISTS (SELECT * 
           FROM   sysobjects 
           WHERE  id = Object_id('[dbo].[sp_cp_test]') 
                  AND Objectproperty(id, 'IsProcedure') = 1 
                  AND xtype = 'p' 
                  AND NAME = 'sp_cp_test') 
  BEGIN 
      SET @Proc=@Alter + @Proc 

      EXEC (@proc) 
  END 
ELSE 
  BEGIN 
      SET @Proc=@Create + @Proc 

      EXEC (@proc) 
  END 

go 
0 голосов
/ 22 ноября 2013

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

IF OBJECT_ID('ValidateRequestPost') IS NULL
BEGIN
    EXEC ('CREATE PROCEDURE ValidateRequestPost 
    @RequestNo VARCHAR(30),
    @ErrorStates VARCHAR(255) OUTPUT
AS
BEGIN
    SELECT @ErrorStates = @ErrorStates
END')
END
...