如何检测存储过程是否已存在

时间:2009-06-02 04:37:19

标签: sql sql-server-2005 stored-procedures

我必须编写一个部署脚本,如果存储过程存在或不存在,该脚本将起作用。即如果它存在,那么我需要改变它,否则创建它。

我怎样才能在sql中执行此操作。

我正在使用SQL Server 2005

11 个答案:

答案 0 :(得分:152)

如果您执行DROP并创建该过程,则会丢失安全设置。这可能会惹恼您的DBA或完全破坏您的应用程序。

我所做的是创建一个简单的存储过程(如果它尚不存在)。之后,您可以根据自己的喜好更改存储过程。

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

这样,安全设置,评论和其他元细节将在部署后继续存在。

答案 1 :(得分:138)

最干净的方法是测试它的存在,如果它存在则删除它,然后重新创建它。您不能在IF语句中嵌入“create proc”语句。这应该做得很好:

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

CREATE PROC MySproc
AS
BEGIN
    ...
END

答案 2 :(得分:30)

如果您只处理存储过程,最简单的方法是删除proc,然后重新创建它。您可以使用SQL Server中的Generate Scripts向导生成所有代码来执行此操作。

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...

答案 3 :(得分:14)

SQL Server 2016 CTP3您可以使用新的 DIE 语句而不是大IF包装

语法:

  

DROP {PROC |程序} [如果存在] {[架构名称。 ]程序}   [,... n]

查询:

DROP PROCEDURE IF EXISTS usp_name

更多信息here

答案 4 :(得分:10)

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是proc名称

答案 5 :(得分:3)

除了已经说过的内容之外,我还想添加一种不同的方法并提倡使用差异脚本部署策略。 Instead of making a stateful script that always checks the current state and acts based on that state, deploy via a series of stateless scripts that upgrade from well known versions。我已经使用了这种策略,因为我的部署脚本现在都是“IF”免费的,所以它可以节省大量时间。

答案 6 :(得分:2)

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

答案 7 :(得分:0)

更好的选择可能是使用Red-Gate SQL Compare或SQL Examiner等工具自动比较差异并生成迁移脚本。

答案 8 :(得分:0)

我有一个存储过程,允许客户扩展验证,如果它存在我不想改变它,如果它不是我想创建它,我发现的最佳方式:

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

答案 9 :(得分:0)

以下代码将检查存储过程是否已存在。

如果它存在则会改变,如果它不存在,它将为您创建一个新的存储过程:

//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 

答案 10 :(得分:0)

您可以编写如下查询:

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

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

更详细地说明上述语法:
OBJECT_ID 是数据库中对象的唯一ID号,由SQL Server在内部使用。由于我们传递的是 ProcedureName ,然后是对象类型 P ,它告诉SQL Server您应该找到名为 ProcedureName 的对象,该对象的类型为< strong>过程,即P

此查询将找到该过程,如果可用,它将删除它并创建一个新过程。

有关OBJECT_ID和对象类型的详细信息,请访问: SYS.Objects