Как определить, существует ли хранимая процедура

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

Как это сделать в sql.

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

Ответ 1

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

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

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

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

Ответ 2

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

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

CREATE PROC MySproc
AS
BEGIN
    ...
END

Ответ 3

Если вы имеете дело только с хранимыми процедурами, самое легкое, что нужно сделать, это, возможно, отказаться от proc, а затем воссоздать его. Вы можете создать весь код для этого, используя мастер создания скриптов в 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...

Ответ 4

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

Синтаксис:

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

Запрос:

DROP PROCEDURE IF EXISTS usp_name

Больше информации здесь

Ответ 5

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 - имя процесса

Ответ 6

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

Ответ 7

IF OBJECT_ID('SPNAME') IS NULL
     -- Does Not Exists
ELSE
     -- Exists

Ответ 8

Лучшим вариантом может быть использование такого инструмента, как Red-Gate SQL Compare или SQL Examiner, для автоматического сравнения различий и создания сценария миграции.

Ответ 9

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

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

Ответ 10

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

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

//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 @[email protected] + @Proc 

      EXEC (@proc) 
  END 
ELSE 
  BEGIN 
      SET @[email protected] + @Proc 

      EXEC (@proc) 
  END 

go 

Ответ 11

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

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