1

我知道有很多问题在问这个问题,但我不明白为什么这段代码会失败,但启动存储过程的“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
4

2 回答 2

4

ACREATE 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在状态缺失时才从外部工具运行该语句。

于 2013-07-26T21:00:38.247 回答
1

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

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

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

于 2013-07-26T22:47:45.793 回答