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
CREATE OR ALTER PROCEDURE [dbo].[ProcToCCreate]
AS
RETURN;
is allowed Syntax in (probably) SQL-Server 2016 (only tested on SQL-Server 2016 with SP1)
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]
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
Related
I am using FOR XML PATH in my stored procedure and so that I need to have QUOTED_IDENTIFIER set to ON. I have it as a first statement of my stored procedure.
SET QUOTED_IDENTIFIER ON;
This is working fine all the times except I restore my database first time.
Just after restoring the database, I checked sp_helptext <SPName> and the stored procedure seems fine.
However when I browse my stored procedure from the Object Explorer and click on "Modify", it shows this:
When I tried executing the stored procedure using EXEC <SP_Name> it throws an error
SELECT failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
Can someone guide me why SQL Server is adding SET QUOTED_IDENTIFIER OFF on its own? How to get rid of it? or How can we overwrite it from within the stored procedure?
If I remove SET QUOTED_IDENTIFIER OFF from the top, re-execute/run it then it will work fine.
My problem is - We have automated process which runs migrations/create database on every build so I can not remove it manually all the times.
I also can not set it on the database level.
I checked the database setting for that and its set to false but that should not make any difference right? As I have it specifically SET To ON inside my stored procedure.
Thank you in advance.
The QUOTED_IDENTIFIER database setting is irrelevant. It's only a default, every client driver sets QUOTED_IDENTIFIER on connecting and overrides the database default.
The SET QUOTED_IDENTIFIER inside the stored procedure is irrelevant; remove it.
SET QUOTED_IDENTIFIER has no effect when it appears in the body of a
stored procedure as static Transact-SQL.
SET QUOTED_IDENTIFIER
The setting for QUOTED_IDENTIFIER which was in force for the batch creating the stored procedure will be stored in the catalog, and used by SSMS to script the stored procedure. It does not matter what the current session setting is, or the database default is, or what the SSMS query options are. If it was created with QUOTED_IDENTIFIER ON it will be scripted with QUOTED_IDENTIFIER ON. You can see the stored setting here in sys.sql_modules.
eg
select uses_quoted_identifier
from sys.sql_modules
where object_id = object_id('MyProc')
So,
However when I browse my stored procedure from the Object Explorer and click on "Modify", it [is scripted with QUOTED_IDENTIFER OFF].
If the setting in sys.sql_modules different than the setting in the generated script, that would be a bug in SSMS/SMO.
And this:
means that the stored procedure was created with QUOTED_IDENTIFIER OFF. As you see the session setting for the session invoking the stored procedure is irrelevant.
When a stored procedure is created, the SET QUOTED_IDENTIFIER and SET
ANSI_NULLS settings are captured and used for subsequent invocations
of that stored procedure.
SET QUOTED_IDENTIFIER
This stored procedure's setting also controls the QUOTED_IDENTIFIER setting for dynamic SQL inside the stored procedure. But inside dynamic SQL you can change the setting.
And so yes
My problem is - We have automated process which runs migrations/create database on every build
This process is broken, as it's creating your proc with QUOTED_IDENTIFIER OFF. If you can't fix it you can work around it by pushing your TSQL into a dynamic batch, and setting QUOTED_IDENTIFIER ON in the dynamic SQL. eg
set quoted_identifier off
go
create or alter procedure foo
as
begin
exec ('set quoted_identifier on; select * from "sys"."objects"')
end
go
exec foo --suceeds
Also you can make your stored procedure create script depend on QUOTED_IDENTIFIER ON so you can't possibly create it with QUOTED_IDENTIFIER OFF, eg
set quoted_identifier off
go
create or alter procedure foo
as
begin
select * from "sys"."objects"
end
fails with
Msg 102, Level 15, State 1, Procedure foo, Line 4 [Batch Start Line 2]
Incorrect syntax near 'sys'.
please test bellow statment:
USE MyDB
GO
SET QUOTED_IDENTIFIER on;
GO
EXISTS ....
BEGIN
EXEC ...
END
How can I validate a full batch(s) of t-sql ,I tried to use Set NOEXEC ON, and it helps only for DML commands, such as Update, Delete, Insert etc.'
here is a sample:
SET NOEXEC ON
GO
SELECT dbo.IncorrectFunctionName()
EXEC IncorrectProcedureName
GO
SET NOEXEC OFF
Output:
Commands completed successfully
and :
SELECT dbo.IncorrectFunctionName()
GO
EXEC IncorrectProcedureName
Output:
Msg 4121, Level 16, State 1, Line 11
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.IncorrectFunctionName", or the name is ambiguous.
Msg 2812, Level 16, State 62, Line 13
Could not find stored procedure 'IncorrectProcedureName'.
EDIT:
it is not only DML commands.
USE AdventureWorks2014
SET NOEXEC ON
GO
UPDATE Person.Address SET AddressID=AddressID
GO
SET NOEXEC OFF
Output:
Msg 8102, Level 16, State 1, Line 4
Cannot update identity column 'AddressID'.
But:
USE AdventureWorks2014
SET NOEXEC ON
GO
UPDATE Person.Address2 SET AddressID=AddressID -- table does not exists
GO
SET NOEXEC OFF
Output:
Commands completed successfully.
just ask for the estimated execution plan
create procedure dbo.procwithnonexistenttable
as
begin
select *
from dbo.atablethatdoesnotexist
end
go
SET SHOWPLAN_TEXT ON;
GO <-- this is needed
exec dbo.procwithnonexistenttable
GO
SET SHOWPLAN_TEXT OFF;
GO
I am writing migration for stored procedure with EF 6
string sqlQuery = #"
/****** Object: StoredProcedure [dbo].[GetSalesByLocation] Script Date: 9/21/2016 8:32:36 AM ******/
SET ANSI_NULLS ON GO
SET QUOTED_IDENTIFIER ON GO
CREATE PROCEDURE [dbo].[GetSalesByLocation]
#MerchantID bigint,
#LocationID bigint,
#AccountAccessID bigint,
#KioskID bigint,
#StartDate DATETIME,
#EndDate DATETIME
AS
BEGIN
.....
END
GO";
Sql(sqlQuery);
when i try to run Update-database command i get below error
Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
Incorrect syntax near 'GO'.
Also when i create SP without
SET ANSI_NULLS ON GO
SET QUOTED_IDENTIFIER ON GO
and open in SQL management studio i can see above statement getting added automatically.
So my question is if i am writing migration for stored procedure do i need to `set ansi null on explicitly?
SET ANSI_NULL and SET QUOTED_IDENTIFIER outside the procedure affects SQL Server behaviour only for the session (so it will not be written in the stored procedure and it will not affect the stored procedure behaviour when the stored procedure will be run).
Also, SET ANSI_NULL ON is the default (try SELECT GETANSINULL() on SQMS) so you could omit it. You can also omit SET QUOTED_IDENTIFIER ON (you are using [] to quote identifiers and not ").
If you need to run more statements on the same connection, in Management Studio you use GO, using ADO you can split them on different execution methods (so you will eventually see errors in the right place). Otherwise you can use ; (in this case probably you can't use ;).
I have this error on executing stored procedure:
INSERT failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
Procedure is created with QUOTED_IDENTIFIER flag set to ON
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'sp_procedure') AND TYPE IN (N'P', N'PC'))
BEGIN
DROP PROCEDURE [dbo].[sp_procedure]
END
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_procedure]
(
#param_1 XML
,#param_2 INT
)
AS
BEGIN
-- CODE
END
SELECT statement from sys.sql_modules shows that uses_quoted_identifiers somehow is set to 0.
I have already tried to execute following code. It run in one batch.
SET QUOTED_IDENTIFIER ON;
EXEC sp_procedure #param_1 = N'<?xml version="1.0" encoding="utf-16"?>
xmlns:xsd="http://www.w3.org/2001/XMLSchema" />', #param_2= 51326
But it does not help.
Each session is created with QUOTED_IDENTIFIER set to 1:
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
Any ideas what can it be?
UPD
Turned out that after running this specific script, there also run lots of other files. And one of them just recreated stored procedure with QUOTED_IDENTIFIER set to OFF.
Thank you for your help
Pleasure make sure the table and view definitions are also created with quoted identifier on.
Quick question I have a database with snapshot enabled using
ALTER DATABASE myDB
SET ALLOW_SNAPSHOT_ISOLATION ON
I'm trying to alter an existing stored procedure to use the transaction isolation level to read uncommitted using as follows:
USE [myDB]
GO
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
GO
/****** Object: StoredProcedure [dbo].[myStoredProcedure] Script Date: 03/27/2012 11:39:24 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[myStoredProcedure]
AS
BEGIN
SELECT *
FROM someTable
END
RETURN 0
But when I reopen the stored procedure the SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED statement is gone.
USE [myDB]
GO
/****** Object: StoredProcedure [dbo].[myStoredProcedure] Script Date: 03/27/2012 11:39:24 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[myStoredProcedure]
AS
BEGIN
SELECT *
FROM someTable
END
RETURN 0
Was the transaction level actually set? I expected the statement to still be there after closing and reopening the stored procedure window. Just wanted to verify, thanks.
You have to put it in the procedure body. If it is outside you are just altering it in that isolation level as opposed to altering the procedure definition to use it.
USE [myDB]
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[myStoredProcedure]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT *
FROM someTable
END