如何在创建存储过程之前检查存储过程是否存在

时间:2013-07-26 20:50:46

标签: sql sql-server stored-procedures

我知道有很多问题要问这个问题,但我不明白为什么这段代码失败了,但启动存储过程的'BEGIN'说它期望“EXTERNAL”没有意义。

IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.Insert_ToTable'))
BEGIN
    CREATE PROCEDURE [dbo].[Insert_ToTable]
    AS
    BEGIN
        BEGIN TRANSACTION
        BEGIN TRY

            //Stored Procedure Code
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;

            DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int

            SELECT @ErrMsg = ERROR_MESSAGE(),
                   @ErrSeverity = ERROR_SEVERITY()

            RAISERROR(@ErrMsg, @ErrSeverity, 1)
        END CATCH   

        IF @@TRANCOUNT > 0
            COMMIT TRANSACTION;
    END
END

2 个答案:

答案 0 :(得分:4)

CREATE PROCEDURE必须是批处理中唯一的语句。如果不存在,则无法有条件地创建它,因为CREATE PROCEDURE前面有if语句。但是,您可以有条件地放弃然后始终创建它。

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Insert_ToTable]') AND type in (N'P', N'PC'))
  drop procedure [dbo].[Insert_ToTable]
go

create procedure [dbo].[Insert_ToTable]
as
  -- code
go

grant execute on [dbo].[Insert_ToTable] to whomever
go

编辑#1

由于您使用的是外部工具,因此可以运行以下语句来测试该过程是否存在:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Insert_ToTable]') AND type in (N'P', N'PC'))
  select 'exists' as [status]
else
  select 'missing' as [status]

然后,您可以轻松测试[status]字段,只有在缺少状态时才从外部工具运行create procedure语句。

答案 1 :(得分:1)

另一个真的,我的意思是真正丑陋的方式是使用EXEC创建存储过程。

IF NOT EXISTS (...)
BEGIN
    EXEC('CREATE PROCEDURE [dbo].[Insert_ToTable] ...')
END

如果您不需要,请不要使用它。