Ошибка SQL: «CREATE / ALTER PROCEDURE» должен быть первым оператором в пакете запроса? - PullRequest
30 голосов
/ 29 января 2012

Я пытаюсь создать сценарий 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

Ответы [ 5 ]

47 голосов
/ 29 января 2012

Запустите ваше заявление в следующей форме:

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

Обратите внимание на GO сепаратор партии после DROP PROCEDURE

26 голосов
/ 29 января 2012

Полученное вами сообщение об ошибке верное. Вы можете прервать пакет (и запустить другой) с помощью ключевого слова GO.

Поместите GO прямо перед оператором Create. Оператор GO должен быть сам по себе.

10 голосов
/ 21 июня 2012

Часто я хочу сделать обратное тому, что вы просите. Например, если пользователь настроил процедуру, и я не хочу потерять их изменения, но я хочу применить единый сценарий обновления для всех моих клиентов, я бы хотел сделать что-то вроде следующего:

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

Эта логика позволила бы мне создавать что-либо, только если этого не существует, но, к моему большому разочарованию, 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

Передав команду create proc в виде строки и поместив ее в выражение exec, мы обойдем глупое правило, которое вообще не позволяет делать это.

6 голосов
/ 27 августа 2015

Моя проблема ушла после того, как я добавил следующие утверждения:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
2 голосов
/ 15 декабря 2015

Возможно, вы захотите попробовать создать хранимую процедуру в другой базе данных, а не создавать ее в текущем контексте.

set @myScript = 'exec '+ QUOTENAME(@DBName) + '..sp_executesql N''create PROCEDURE [dbo].[myproc]
AS
BEGIN
    select * from mytable
END'''
execute(@myScript)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...