2012-01-29 5 views
23

Я пытаюсь создать SQL-скрипт, но получаю сообщение об ошибке:sql error: «CREATE/ALTER PROCEDURE» должно быть первым оператором в пакете запросов?

'CREATE/ALTER PROCEDURE' must be the first statement in a query batch??

Вот мой код:

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 

ответ

21

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

Место GO прямо перед созданием оператора процедуры. Вывод GO должен быть на отдельной строке.

+0

«Инструкция GO должна быть на линии сама по себе». Очень важная часть, чтобы заставить это работать. – Nate

39

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

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

+6

Обратите также внимание, что если за GO следует точка с запятой, сообщение об ошибке будет сохраняться. (SQLSrv, по-видимому, интерпретирует точку с запятой как пустое выражение перед CREATE). Это немного задержало меня. – kmote

+4

Но GO даже недействителен SQL. Это SSMS-команда, не так ли? – xr280xr

+0

@ xr280xr Вы правы, VS разделяет сценарий на партии в соответствии с GO stmt, но точка с запятой не является частью GO –

9

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

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 

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

3

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

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 
2

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

 
set @myScript = 'exec '+ QUOTENAME(@DBName) + '..sp_executesql N''create PROCEDURE [dbo].[myproc] 
AS 
BEGIN 
    select * from mytable 
END''' 
execute(@myScript) 
Смежные вопросы