当我在这里使用IF语句时,为什么CREATE PROCEDURE语句失败?

pen*_*ake 10 t-sql batch-file sql-server-2008

我正在尝试DROP存储过程,如果它存在,然后通过这样方式创建它:

IF OBJECT_ID('[dbo].[myStoredProc]') IS not NULL
    DROP PROCEDURE dbo.myStoredProc


CREATE PROCEDURE [dbo].[myStoredProc]
(
    @parameter1 BIT
) AS

IF @parameter1 = 1
    BEGIN
             ....
Run Code Online (Sandbox Code Playgroud)

但它抱怨说:

"CREATE PROCEDURE必须是批次中唯一的声明"

问题:如何修复脚本以克服这个问题?

小智 17

您需要go在第一个逻辑批次结束时放置一个.

IF OBJECT_ID('[dbo].[myStoredProc]') IS not NULL
    DROP PROCEDURE dbo.myStoredProc
go -- you need to add the batch-terminator 'go'


CREATE PROCEDURE [dbo].[myStoredProc]
(
    @parameter1 BIT
) AS

IF @parameter1 = 1
    BEGIN
             ..
Run Code Online (Sandbox Code Playgroud)

  • @pencilCake:我认为,对于可能包含在定义中的确切内容可能会产生混淆.假设它们允许您将过程创建与其他语句混合使用.然后,人们自然希望不仅可以在过程定义之前放置语句,而且也可以在它之后放置语句,作为一些对象创建逻辑的一部分.但是你怎么知道定义在哪里结束?全局`BEGIN ... END`关键字不是强制性的,任何数量的语句都可以遵循`AS` - 那么,哪一个不再是程序的一部分而是属于'外部'脚本? (2认同)
  • @pencilCake:另一件事:你可以在`CREATE/ALTER PROCEDURE`之前添加注释和/或任意数量的空行,解析器将它们包含在定义中.但是如果`CREATE PROCEDURE`和前面的语句之间有一个注释部分,那么解析器如何"知道"注释是属于前一个语句还是属于过程?所以,最终,我猜,他们最终得到了上述限制:你只在一个单独的批次中定义一个程序(以及一个函数,一个视图,一个触发器). (2认同)

Cur*_*urt 8

在语句后添加GOIF表明这是第一个查询批处理的结束.

在这里阅读更多:

http://msdn.microsoft.com/en-us/library/ms188037.aspx

IF OBJECT_ID('[dbo].[myStoredProc]') IS not NULL
    DROP PROCEDURE dbo.myStoredProc
GO
Run Code Online (Sandbox Code Playgroud)

这样可以防止您的错误发生.