SQL Server Stored Procedure Fails due to use of XML/ ANSI_NULLS, QUOTED_IDENTIFIER options - sql

I have a stored procedure which takes an XML parameter and inserts the data into multiple tables. If I run the stored procedure into a database using a SSMS query window, everything works fine. However, we have a custom installation program that is used to deploy stored procedures to databases, and when this is used, execution of the sp fails with this error:
INSERT failed because the following SET options have incorrect settings:
'ANSI_NULLS, QUOTED_IDENTIFIER'. Verify that SET options are correct for use with
indexed views and/or indexes on computed columns and/or query notifications
and/or xml data type methods.
The custom installation program does not use the correct settings when scripting in the stored procedures.
Setting these ( SET ARITHABORT ON; SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON;) within the sp has no effect:
I have also tried setting these options for the open connection just before calling the sp in the code. This again does not have the desired effect.
It appears that the settings on the connection to the database while the sp is being run in to the database are what matters, not the settings when the sp is used.
I have experimented by playing with these settings in SSMS options, and this does appear to be the case. I would just like someone to confirm that this is definitely the case (if there is a way around I would love to hear it, but I'm not hopeful)
Unfortunately altering the installer program is not an option for me at the present time, so I'm looking at having to roll back a couple of weeks work; so if I do have to do this I want to be really sure (and have some evidence to back me up) that this is the only option

The settings applied with those at CREATE or ALTER time and are ignored at runtime.
SSMS has correct settings by default (so does sqlcmd, osql etc).
From BOL, CREATE PROC, "Using SET Options"
The Database Engine saves the settings
of both SET QUOTED_IDENTIFIER and SET
ANSI_NULLS when a Transact-SQL stored
procedure is created or modified.
These original settings are used when
the stored procedure is executed.
Therefore, any client session settings
for SET QUOTED_IDENTIFIER and SET
ANSI_NULLS are ignored when the stored
procedure is running. Other SET
options, such as SET ARITHABORT, SET
ANSI_WARNINGS, or SET ANSI_PADDINGS
are not saved when a stored procedure
is created or modified.

Related

Is there any way to set ansi_nulls on for multiple stored procedures at once with writing a script and not making changes to any system table?

I have about 100 of stored procedures with ansi_nulls off, and I am trying to set it ON. One way I can go to each stored procedure and set property>options>ansi_nulls ON, also can modify each of them with ansi_nulls ON and compile it. But it is very much time consuming to do for hundreds of SPs.
I would like to have a way where I can write a script to modify them with ansi_nulls on and execute it in same script without touching any system table.
Well, I can use sys tables to just query the SPs to list them which I need to modify.
I appreciate your help, thanks in advance.
What I would do and it certainly isn't time consuming:
In SQL Server Management Studio, right click the database in Object Explorer, go to Tasks, and Generate Scripts
Select "Select specific database objects" and check "Stored Procedures" and click Next
The default should be good (single file) on the Set Scripting Options screen except you need to pick your file output. Click Next and then Next again. It'll take a minute or five to generate the file.
Open the text/SQL file generated in a decent editor like Notepad++.
Mass replace CREATE PROCEDURE with ALTER PROCEDURE
If SET ANSI_NULLS OFF was created in the script, replace SET ANSI_NULLS OFF with SET ANSI_NULLS ON.
If SET ANSI_NULLS OFF was not created, replace ALTER PROCEDURE with SET ANSI_NULLS ON\r\nGO\r\nALTER PROCEDURE where \r\n is of course a Carriage Return Line Feed combo. If your text editor can't create CrLFs, get a better text editor.
The text file should now be good to execute to correct the issue. Test this before running the whole thing. Also, be sure to keep a backup of the original script.

SET ANSI_NULLS ON Default

New to the forums and SQL Server so just trying to boost my rating and ask some simple questions.
I have a list of hundreds of stored procedures and on all of them they all say SET ANSI_NULLS ON
is there a way to default this so that you do not have to declare it in the beginning of each script?
It's not literally stored within the stored procedure.
The setting is captured when a stored procedure is created, and when you ask SQL Server to script a stored procedure, it adds the appropriate setting above the CREATE PROCEDURE so that you can recreate the stored procedure accurately.
See CREATE PROCEDURE:
The Database Engine saves the settings of both SET QUOTED_IDENTIFIER and SET ANSI_NULLS when a Transact-SQL procedure is created or modified. These original settings are used when the procedure is executed. Therefore, any client session settings for SET QUOTED_IDENTIFIER and SET ANSI_NULLS are ignored when the procedure is running.
And sys.sql_modules:
uses_ansi_nulls bit Module was created with SET ANSI_NULLS ON.

How to change ANSI_NULLS remotely for a procedure or migrate procedure with ANSI_NULLS set OFF

I know there are numerous topics regarding migrating or syncing stored procedures to another server, anyhow, I'm not able to find out some acceptable answer to following question.
I want to migrate stored procedure with ANSI_NULL value set to OFF by a script.
Example of the procedure I want to migrate:
USE [myDB]
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[p_test_ansi_nulls] AS
SELECT CASE WHEN NULL = NULL THEN 'haha' ELSE 'no-haha' END h
ANSI_NULLS value is stored in sys.sql_modules table, but not in the procedure itself. I tried to create statement with the header (with SET ANSI_NULLS OFF string included) and execute via sp_executesql, but got an error:
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
So is there any way, how to migrate procedure to another server with this option or way how to change this setting remotely?
(procedure is quite old and complex, therefore we can't change the code..)
Do it exactly the way you wrote up there.
SET ANSI_NULLS OFF
GO
CREATE PROCEDURE [dbo].[p_test_ansi_nulls] AS
SELECT CASE WHEN NULL = NULL THEN 'haha' ELSE 'no-haha' END h
This will create procedure with ANSI_NULLS off:
SQLFiddle DEMO
Also, pease note - from msdn: http://msdn.microsoft.com/en-us/library/ms188048.aspx
In a future version of SQL Server, ANSI_NULLS will always be ON and any applications that explicitly set the option to OFF will generate an error. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.

Stored procedure will not display in object explorer?

USE [MASTER]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
USE [MASTER]
GO
CREATE PROCEDURE [dbo].[TOTALLY_NEW] #FISCAL_YEAR NVARCHAR(4) AS
BEGIN
PRINT 'HERE'
END
GO
select * from master..sysobjects
where name like 'tot%' <-- returns one row!!!!!!
I've refreshed this list a dozen times..!!
I've tried disconnecting and reconnecting..
I've created all those other SP's listed in the image before.
Here is a picture with more.
Ensure that the user you are using has permissions to view stored procedures. I am not 100% on SQL Server which permission this is but I have seen this problem on a few other databases where a user creates a SP, but another user does not have permission to view or list the SPs.
Per request, converting comment to answer:
Yes, you shouldn't be creating user objects in master. The only time I ever do it is when I explicitly want to create a utility procedure that I can call from any database using that database's context, which you have to do on purpose and doesn't happen by accident - so I suspect you inadvertently marked your object as a system procedure. You do this using EXEC sp_MS_marksystemobject (or in older versions by having set EXEC sp_MS_upd_sysobj_category 1 - the latter might work in 2005 with 80 compatibility, not sure).

UPDATE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'

I am having a problem with an update stored procedure. The error is:
UPDATE 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 query notifications and/or xml data type methods.
SQL State: 42000
Native Error: 1934
Unfortunately, there are no indexed views, computed columns, or query notifications for this table. This Stored Procedure was running fine for past couple of days and since today has been returning this error.
Is there any suggestion that would help in identifying the problem?
Note: If I set the quoted_identifier to ON and rerun the CREATE PROCEDURE, the issue will be fixed (for now). But I want to understand what triggered this issue in the first place.
To avoid that error, I needed to add
SET ANSI_NULLS, QUOTED_IDENTIFIER ON;
for all my stored procs editing a table with a computed column.
You don't need to add the SET inside the proc, just use it during creation, like this:
SET ANSI_NULLS, QUOTED_IDENTIFIER ON;
GO
CREATE PROCEDURE dbo.proc_myproc
...
I got this error when I tried to run an sql file via the command line with sqlcmd:
sqlcmd -i myfile.sql
By default QUOTED_IDENTIFIER is set to OFF when using this command line tool and you will get the same error (no matter that in the SSMS it may be set to ON and the same script will pass).
So indeed the solution is to add this QUOTED_IDENTIFIER ON to your sql file like Jim suggested, or explicitly specify the flag -I:
sqlcmd -i myfile.sql -I
We cannot create a indexed view by setting the quoted identifier off. I just tried it and SQL 2005 throws an error straight away if it is turned off:
Cannot create index. Object 'SmartListVW' was created with the following SET options off: 'QUOTED_IDENTIFIER'.
As gbn said, rebuilding the indexes must be the only other way it got turned off.
I have seen lots of articles saying it must be on before creating index on views. Otherwise you would get an error while inserting, updating the table, but here I can get the error straight away, so sql engine won't allow to create index on views by setting it to off, per this msdn link.
I have asked a similar question here in stack sometime ago...
EDIT
I turned off the global queryexecution (in editor) ANSI settings and ran the index script in new editor, this time also it throws the same error. So it's clear we can't create indexes on views by turning off quoted_identifier.
I'm late to this party but had this error and wanted to share it.
Our problem was recurrent but random so we knew it wasn't an object that had been created incorrectly.
We finally tracked it down to an ODBC connection on one of the servers in our Citrix farm. On that server, the ODBC in question had had its QUOTED_IDENTIFIERS turned off (unchecked). On all the other servers, it was checked as expected. We turned the option on and the problem was instantly solved.
I got this error when I run SQL Agent Job, which has 3 steps T-sql scripts.
Msg 1934, Sev 16, State 1, Line 15 : UPDATE 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. [SQLSTATE 42000]
I added
SET ANSI_NULLS, QUOTED_IDENTIFIER ON; to the top of the Agent Job and that solved the issue.
Some thoughts:
Did indexes get rebuilt? If you do index maintenance using DMO, then quoted_identifier will not always be preserved. It can be a pain to track down and was a particular problem is SQL Server 2000 until SP4 or so.
However, I've seen on SQL Server 2005 some time ago too.
SELECT
OBJECT_NAME (sm.object_id) AS [Name],
sm.uses_ansi_nulls,
sm.uses_quoted_identifier,
N'SET ANSI_NULLS, QUOTED_IDENTIFIER ON;
--change the below CREATE to an ALTER.
GO
' + sm.definition AS PossibleFixingStatement
FROM
sys.sql_modules AS sm
WHERE
1 = 1
AND
(
sm.uses_ansi_nulls <> 1
OR sm.uses_quoted_identifier <> 1
)
AND NOT EXISTS
(
SELECT
*
FROM
sys.objects AS o
WHERE
o.is_ms_shipped = 1
AND o.object_id = sm.[object_id]
)
ORDER BY
sm.uses_ansi_nulls,
sm.uses_quoted_identifier;
Query to identify the affected objects. Part of the sp_blitz procedure mentioned here at https://github.com/BrentOzarULTD/SQL-Server-First-Responder-Kit/issues/1698
I got this error today running a stored procedure in SSMS. Disconnecting from the server and reconnecting with a new session solved the problem for me. The SP I was running had never had this problem before.
I got the same error running this query in the Job Scheduler SQL Server Agent
UPDATE [Order]
SET OrderStatusID = 100
WHERE OrderStatusID = 200
AND OrderID IN (
[...]
)
I solved removing the [ ] characters from [Order]:
UPDATE Order
SET OrderStatusID = 100
WHERE OrderStatusID = 200
AND OrderID IN (
[...]
)
No more errors
I got the same error, had to add a couple of settings to get it resolved:
SET ANSI_NULLS ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET ARITHABORT ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET NUMERIC_ROUNDABORT OFF;
SET QUOTED_IDENTIFIER OFF;
SET NOCOUNT ON;