Creating a stored procedure if it does not already exist

后端 未结 9 1022
谎友^
谎友^ 2021-02-05 01:12

I want to check if a list of stored procedures exist. I want this all to be done in 1 script, one by one. So far I have this format:

USE [myDatabase]
GO

IF NO         


        
相关标签:
9条回答
  • 2021-02-05 01:29

    One idiom that I've been using lately that I like quite a lot is:

    if exists (select 1 from sys.objects where object_id = object_id('dbo.yourProc'))
       set noexec on
    go
    create procedure dbo.yourProc as
    begin
       select 1 as [not yet implemented]
    end
    go
    set noexec off
    alter procedure dbo.yourProc as
    begin
       /*body of procedure here*/
    end
    

    Essentially, you're creating a stub if the procedure doesn't exist and then altering either the stub (if it was just created) or the pre-existing procedure. The nice thing about this is that you don't drop a pre-existing procedure which drops all the permissions as well. You can also cause issues with any application that happens to want it in that brief instant where it doesn't exist.

    [Edit 2018-02-09] - In SQL 2016 SP1, create procedure and drop procedure got some syntactic sugar that helps with this kind of thing. Specifically, you can now do this:

    create or alter dbo.yourProc as
    go
    
    drop procedure if exists dbo.yourProc;
    

    Both provide idempotency in the intended statement (i.e. you can run it multiple times and the desired state). This is how I'd do it now (assuming you're on a version of SQL Server that supports it).

    0 讨论(0)
  • 2021-02-05 01:38
    USE [myDatabase]
    GO
    
    IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'sp_1')
    BEGIN
      DROP PROCEDURE sp_1
    END
    GO   --<-- Add a Batch Separator here
    
    
    
    CREATE PROCEDURE sp_1
    AS
    .................
    END
    GO
    
    0 讨论(0)
  • 2021-02-05 01:42

    CREATE PROCEDURE must be the first statement in the batch. I usually do something like this:

    IF EXISTS (
            SELECT type_desc, type
            FROM sys.procedures WITH(NOLOCK)
            WHERE NAME = 'myProc'
                AND type = 'P'
          )
         DROP PROCEDURE dbo.myProc
    GO
    
    CREATE PROC dbo.myProc
    
    AS
    ....
    
        GO
        GRANT EXECUTE ON dbo.myProc TO MyUser 
    

    (don't forget grant statements since they'll be lost if you recreate your proc)

    One other thing to consider when you are deploying stored procedures is that a drop can succeed and a create fail. I always write my SQL scripts with a rollback in the event of a problem. Just make sure you don't accidentally delete the commit/rollback code at the end, otherwise your DBA might crane-kick you in the trachea :)

    BEGIN TRAN 
    IF EXISTS (
           SELECT type_desc, type
           FROM sys.procedures WITH(NOLOCK)
           WHERE NAME = 'myProc'
               AND type = 'P'
         )
    DROP PROCEDURE myProc GO
    CREATE PROCEDURE myProc
       
    AS
       --proc logic here
    
    GO
    -- BEGIN DO NOT REMOVE THIS CODE (it commits or rolls back the stored procedure drop) 
        IF EXISTS(
                   SELECT 1
                   FROM sys.procedures WITH(NOLOCK)
                   WHERE NAME = 'myProc'
                       AND type = 'P'
                 )
            COMMIT TRAN
            ELSE
            ROLLBACK TRAN
    -- END DO NOT REMOVE THIS CODE
    
    0 讨论(0)
  • 2021-02-05 01:45

    you can execute the following:

    DROP PROCEDURE IF EXISTS name_of_procedure;
    CREATE PROCEDURE name_of_procedure(....)
    
    0 讨论(0)
  • 2021-02-05 01:47

    Just in case if you are using SQL server 2016, then there is a shorter version to check if the proc exist and then drop and recreate it

    USE [DATABASENAME]
    GO
    DROP PROCEDURE IF EXISTS <proc name>
    GO
    CREATE PROCEDURE <proc name>
    AS
    -- your script here
    END
    GO
    GRANT EXECUTE ON <proc name> TO <username>
    

    Source : https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016/

    0 讨论(0)
  • 2021-02-05 01:48
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[spGetRailItems]') AND type in (N'P', N'PC'))
    BEGIN 
    execute ('
    CREATE PROCEDURE [dbo].[spGetRailItems]  
    AS  
    BEGIN  
    
    Declare @isLiftedBagsEnable bit=1;  
    select @isLiftedBagsEnable=cast(DataValu as bit) from setups where scope =''Rail Setting'' and dataName = ''isLiftedBagsEnable'';
    
    IF @isLiftedBagsEnable=1
    BEGIN
        IF EXISTS (SELECT * FROM ITEMCONFIG)
        BEGIN
            SELECT [Item],[Desc] FROM ProcData WHERE Item IN (SELECT Item FROM ItemConfig) ORDER BY [Desc]
        END
        ELSE
        BEGIN
            SELECT [Item],[Desc] FROM ProcData ORDER BY [Desc]
        END
    END
    ELSE
    BEGIN
        SELECT [Item],[Desc] FROM ProcData ORDER BY [Desc]
    END
    
    END
    
    ')
    END
    
    exec spGetRailItems;
    
    0 讨论(0)
提交回复
热议问题