SQL错误:'CREATE/ALTER PROCEDURE'必须是查询批处理中的第一个语句?

use*_*007 31 t-sql sql-server-2008

我试图创建一个SQL脚本但收到错误:

'CREATE/ALTER PROCEDURE'必须是查询批处理中的第一个语句?

这是我的代码:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'myproc') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[myproc]

create PROCEDURE [dbo].[myproc]

AS
BEGIN
    select * from mytable
END
GO
Run Code Online (Sandbox Code Playgroud)

Ole*_*Dok 49

以下列形式运行您的声明:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'myproc') AND type in (N'P', N'PC'))
  DROP PROCEDURE [dbo].[myproc]
GO
create PROCEDURE [dbo].[myproc]
AS
BEGIN
    select * from mytable
END
GO
Run Code Online (Sandbox Code Playgroud)

注意之后的GO批处理分隔符DROP PROCEDURE

  • 另请注意,如果GO后跟分号,则错误消息将保持不变.(SQLSrv显然在CREATE之前将分号解释为空语句).这一次困扰了我一段时间. (8认同)
  • 但GO甚至不是有效的SQL.这是一个SSMS命令不是吗? (5认同)

jln*_*thy 29

您收到的错误消息是正确的.您可以使用GO关键字终止批处理(并启动另一个批处理).

将GO放在Create过程语句之前.GO语句必须单独排在一行.

  • “ GO语句本身必须在一行上。” 使它正常工作的非常重要的部分。 (2认同)

Ste*_*e L 11

我经常希望与你所要求的相反.例如,如果用户已经自定义了一个过程,并且我不想丢失他们的更改,但我想为所有客户端应用统一的更新脚本,我希望能够执行以下操作:

if not exists ( select * from sys.objects 
            where name='myProc' and objectproperty(object_id,'IsProcedure')=1 )
create proc myProc 
as begin
  -- proc stmts here
end
go
Run Code Online (Sandbox Code Playgroud)

这个逻辑只允许我创建一些东西,如果它不存在,但令我非常沮丧的是,SQL Server也阻止了这一点.

我很容易解决这个问题如下:

if not exists ( select * from sys.objects 
            where name='myProc' and objectproperty(object_id,'IsProcedure')=1 )
exec('create proc myProc 
as begin
  -- proc stmts here
  declare @object int = 0
end')
go
Run Code Online (Sandbox Code Playgroud)

通过将create proc命令作为字符串传递并将其放在exec语句中,我们绕过了阻止人们首先执行此操作的愚蠢规则.


小智 6

添加以下语句后,我的问题消失了:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
Run Code Online (Sandbox Code Playgroud)

  • 解决方法不是 ansi_null = on 和 Quoted_identifier = on,而是将脚本分开执行的 go (3认同)