Create alter procedure должна быть первой инструкцией в пакетном запросе

Often I wish to do the reverse of what you are asking. For example if the user has customized a procedure, and I don’t want to lose their changes, yet I want to apply a uniform update script for all my clients, I’d like to be able to do something like the following:

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

This logic would allow me to create something only if it DOESN’T exist, but to my great frustration, SQL Server prevents this too.

I get around this problem easily enough as follows:

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

By passing the create proc command as a string and placing it in an exec statement we circumvent the stupid rule that prevents one from doing this in the first place.

Problem

When you’re executing a CREATE/ALTER statement to create a procedure/view/function/trigger, you get one of the following errors:

‘CREATE/ALTER PROCEDURE’ must be the first statement in a query batch

‘CREATE VIEW’ must be the first statement in a query batch.

‘CREATE FUNCTION’ must be the first statement in a query batch.

‘CREATE TRIGGER’ must be the first statement in a query batch.

You can’t execute these CREATE/ALTER statements with other statements.

Solution

The solution is to execute the CREATE/ALTER statement separately from other statements. How you do that depends on if you’re using SSMS/sqlcmd/osql or executing from C#.

If you’re executing from SSMS (or sqlcmd/osql)

Add the keyword GO right before CREATE statement. This is the default batch separator in SSMS. It splits the query into multiple batches. In other words, it executes the CREATE statement by itself in its own batch, therefore solving the problem of it needing to be the first statement in a batch. Here’s an example:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'spGetAllPosts') AND type in (N'P', N'PC'))
	DROP PROCEDURE [dbo].spGetAllPosts
GO
CREATE PROCEDURE [dbo].spGetAllPosts
AS
BEGIN
    SELECT * FROM Posts
END
Code language: SQL (Structured Query Language) (sql)

If you’re executing from C#

You can’t use the GO keyword in C#. Instead you have to execute the two queries separately. The best way to do that is to execute the first part, then change the CommandText and execute the second part.

using System.Data.SqlClient;

string dropProcQuery = 
	@"IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'spGetAllPosts') AND type in (N'P', N'PC'))
		DROP PROCEDURE[dbo].spGetAllPosts";
		
string createProcQuery = 
	@"CREATE PROCEDURE [dbo].spGetAllPosts
	AS
	BEGIN
		SELECT * FROM Posts
	END";
	
using (var con = new SqlConnection(ConnectionString))
{
	using (var cmd = new SqlCommand(dropProcQuery, con))
	{
	        //Execute the first statement
		con.Open();
		cmd.ExecuteNonQuery();
		
		//Then execute the CREATE statement
		cmd.CommandText = createProcQuery;
		cmd.ExecuteNonQuery();
	}
}

Code language: C# (cs)

I am trying to create a stored procedure in the database called DB_Interface like this:

USE [DB_Interface]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE OR ALTER PROCEDURE [dbo].[ProcToCCreate]

It throws error:

Msg 156, Level 15, State 1, Line 6
Incorrect syntax near the keyword ‘OR’.

Msg 111, Level 15, State 1, Line 10
‘CREATE/ALTER PROCEDURE’ must be the first statement in a query batch.`

This is my first stored procedure — not sure if I cannot use Create or Alter like I used it. Any help is greatly appreciated

marc_s's user avatar

marc_s

733k175 gold badges1330 silver badges1459 bronze badges

asked Dec 21, 2016 at 5:10

trx's user avatar

4

CREATE OR ALTER  PROCEDURE [dbo].[ProcToCCreate]
AS
RETURN;

is allowed Syntax in (probably) SQL-Server 2016 (only tested on SQL-Server 2016 with SP1)

answered Dec 22, 2016 at 10:02

Ebis's user avatar

EbisEbis

3801 silver badge4 bronze badges

CREATE  PROCEDURE [dbo].[ProcToCCreate]

OR

CREATE  PROC [dbo].[ProcToCCreate]

are only valid syntax in SQL Server.

If you want to ALTER procedure, here is the syntax

 ALTER  PROCEDURE [dbo].[ProcToCCreate]

answered Dec 21, 2016 at 5:13

Sateesh Pagolu's user avatar

Sateesh PagoluSateesh Pagolu

9,2822 gold badges30 silver badges48 bronze badges

4

CREATE:

USE [DB_Interface]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[ProcToCCreate]

AS

RETURN

ALTER:

    USE [DB_Interface]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO

    ALTER PROCEDURE [dbo].[ProcToCCreate]

    AS

    RETURN

answered Dec 21, 2016 at 5:19

Genish Parvadia's user avatar

Genish ParvadiaGenish Parvadia

1,4373 gold badges17 silver badges30 bronze badges

try this

GO
declare @sqlCmd varchar(max)
select @sqlCmd =

GO
USE [CRM]
ALTER PROC [dbo].[uspReportTrasnlationOpticalCabinetToNormal]
(
@requestsId varchar(max) = null
—@IsSuccess bit output
)
AS
BEGIN
Set XACT_ABORT ON
SET NOCOUNT ON
BEGIN TRY

—SELECT @IsSuccess = 0
SELECT
R.ID RequestID,
TC.ToTelephoneNo,
TC.FromTelephoneNo,
ISNULL(C.FirstNameOrTitle,»») FirstNameOrTitle,
ISNULL(C.LastName,»») LastName,
ISNULL(A.AddressContent,»») InstallAddress,
ISNULL(A.PostalCode,»») InstallPostalCode,
ISNULL(AA.AddressContent,») CorrespondenceAddress,
ISNULL(AA.PostalCode,»») CorrespondencePostalCode
FROM
Request R
INNER JOIN
TranslationOpticalCabinetToNormal TN ON TN.ID = R.ID
INNER JOIN
TranslationOpticalCabinetToNormalConncetions TC ON TN.ID = TC.RequestID
LEFT JOIN
[Address] A ON A.ID = TC.InstallAddressID
LEFT JOIN
[Address] AA ON AA.ID = TC.CorrespondenceAddressID
LEFT JOIN
Customer C ON C.ID = TC.CustomerID
WHERE
TN.[Type] = 2
AND
(@requestsId IS NULL OR LEN(@requestsId) = 0 OR R.ID IN (SELECT * FROM DBO.ufnSplitList(@requestsId)))

—SELECT @IsSuccess = 1
END TRY
BEGIN CATCH
EXEC [dbo].[uspLogError]
—SELECT @IsSuccess = 0;
THROW;
END CATCH
END


EXECUTE (@sqlCmd) AT [mylinkedserver]
GO

Я пытаюсь создать sql script, но получаю сообщение об ошибке:

‘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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Поместите GO прямо перед оператором Create procedure. Вывод GO должен быть на отдельной строке.

Ответ 3

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

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

Ответ 4

Моя проблема исчезла после добавления следующих утверждений:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

Ответ 5

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

set @myScript = 'exec '+ QUOTENAME(@DBName) + '..sp_executesql N''create PROCEDURE [dbo].[myproc]
AS
BEGIN
    select * from mytable
END'''
execute(@myScript)

Это тоже интересно:

  • Crocodile car body sealant инструкция
  • Crocodile balm инструкция по применению
  • Croc n roll игра инструкция
  • Crm как работать в этой программе инструкция по применению
  • Crm в 1с унф инструкция

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии