SQL Server ANSI_Padding - sql-server

If I right click on a table in SQL Server Management Studio and select 'Script table as > Create to > New Query Editor Window' the code that appears contains:
SET ANSI_PADDING ON
.... create the table ...
SET ANSI_PADDING OFF
So, I guess, whether ANSI_Padding is on or off affects the whole database and it is turned on to create a table and then turned off again?
What happens if you create a table with ANSI_Padding off? How can you turn it on for that table?

SET ANSI_PADDING Controls the way
the column stores values shorter than
the defined size of the column, and
the way the column stores values that
have trailing blanks in char, varchar,
binary, and varbinary data.
In a future version of MicrosoftSQL Server ANSI_PADDING will
always be ON and any applications that
explicitly set the option to OFF will
produce an error. Avoid using this
feature in new development work, and
plan to modify applications that
currently use this feature.
This setting affects only the definition of new columns. After the column is created, SQL Server stores the values based on the setting when the column was created. Existing columns are not affected by a later change to this setting.

So, I guess, whether ANSI_Padding is on or off affects the whole database and it is turned on to create a table and then turned off again?
no, the SET option only affects the context of your connection, if 2 connections come in and one has ANSI_PADDING OFF and the other one ON they don't affect the other connection. However....the table created in one connection will have the behavior that the setting did to it.
read more here http://msdn.microsoft.com/en-us/library/ms190356.aspx
So if connection 1 comes in with set ansi_nulls off
then select * from bla where col = null will work
this however won't work for connection 2 if it comes with with the default ansi_nulls setting (ON)
you can see what you settings are by either executing dbcc useroptions or if you are on 2005 and up
SELECT SPID,VALUE,ANSI_SETTING
FROM (
SELECT ##SPID AS SPID,
CASE quoted_identifier
WHEN 1 THEN 'SET' ELSE 'OFF' END QUOTED_IDENTIFIER,
CASE arithabort
WHEN 1 THEN 'SET' ELSE 'OFF' END ARITHABORT,
CASE ansi_null_dflt_on
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_NULL_DFLT_ON,
CASE ansi_defaults
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_DEFAULTS ,
CASE ansi_warnings
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_WARNINGS,
CASE ansi_padding
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_PADDING,
CASE ansi_nulls
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_NULLS,
CASE concat_null_yields_null
WHEN 1 THEN 'SET' ELSE 'OFF' END CONCAT_NULL_YIELDS_NULL
FROM sys.dm_exec_sessions
WHERE session_id = ##SPID ) P
UNPIVOT (VALUE FOR ANSI_SETTING IN(
QUOTED_IDENTIFIER,ARITHABORT,ANSI_NULL_DFLT_ON,
ANSI_DEFAULTS,ANSI_WARNINGS,
ANSI_PADDING,ANSI_NULLS,CONCAT_NULL_YIELDS_NULL
)
) AS unpvt

Related

Problem to drop a table because of tr_MStran_droptable

I have several databases with similar structures on several servers. I have a job who drop a table and recreate it in the night for every database. But I had a problem with only one database on one server :
Invalid value given for parameter #procmapid. Specify a valid
parameter value.
I made some research and I have seen that the problem was because the trigger tr_MStran_droptable was enabled. So I disable it and now it works. But on my other database this trigger is enabled too and I can drop the table.
How it is possible? I can't find this trigger structure to study it in the database too. Did somebody know more about the trigger tr_MStran_droptable?
Trigger code :
CREATE TRIGGER [tr_MStran_droptable] ON DATABASE
FOR DROP_TABLE AS
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 ON
DECLARE #EventData XML
SET #EventData = EventData()
IF object_id('dbo.sysarticles') IS NULL
OR object_id('dbo.syspublications') IS NULL
OR object_id('dbo.sysextendedarticlesview') IS NULL
OR EXISTS (
SELECT 1
FROM #EventData.nodes('/EVENT_INSTANCE') AS R(event_instance)
WHERE lower(event_instance.value('SchemaName[1]', 'sysname')) IN (
N'sys'
,N'cdc'
)
OR lower(event_instance.value('ObjectName[1]', 'sysname')) IN (
N'sysextendedarticlesview'
,N'sysarticles'
,N'syspublications'
)
OR event_instance.value('ObjectName[1]', 'sysname') LIKE N'#%'
)
RETURN
EXEC sys.sp_MStran_ddlrepl #EventData
,5
GO
DISABLE TRIGGER [tr_MStran_droptable] ON DATABASE
GO
It's Because of the trigger :
The trigger is to keep replication alive so :
Try running sp_removedbreplication 'CurrentDatabase' that will remove replication
or
Disable Trigger : DISABLE TRIGGER [tr_MStran_droptable] ON DATABASE

MSSQL 2012 64 bit ANSI_PADDING error inconsistent results across connections

I have two connections to the same db on the same server, with the same user,
as open windows in Sequel Server Management studio.
On the first I run:
BEGIN TRANSACTION T1
SET ANSI_PADDING ON
SET CONCAT_NULL_YIELDS_NULL ON
SET QUOTED_IDENTIFIER ON;
SET NUMERIC_ROUNDABORT OFF
SET ARITHABORT OFF
SET ANSI_WARNINGS ON
SET ANSI_NULLS ON
DELETE from GPSData where GPSDateTime BETWEEN '2014-06-09' AND '2014-06-11'
COMMIT TRANSACTION T1
and the error is:
Msg 1934, Level 16, State 1, Line 8
DELETE failed because the following SET options have incorrect settings: 'ANSI_NULLS, CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING'. 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.
When I run the same transaction on the other connection, the error is:
The DELETE statement conflicted with the REFERENCE constraint "FK_GPSUnit_GPSData". The conflict occurred in database "PLATO_PEP", table "dbo.GPSUnit", column 'GPSDataID'.
The statement has been terminated.
The second error I expect to see. How can the first connection give an ANSI_PADDING... error, when the same settings work on the second connection?

How is the default value for CONCAT_NULL_YIELDS_NULL determined at runtime by MS SQL

Per the Microsoft Documentation for MS SQL 2008R2,
1)If SET CONCAT_NULL_YIELDS is not specified, the setting of the CONCAT_NULL_YIELDS_NULL database option applies
2)The setting of SET CONCAT_NULL_YIELDS_NULL is set at execute or run time and not at parse time
I interpret this as
As soon as you connect to the database without providing a SET CONCAT_NULL_YIELDS_NULL command , it will set it by default from the database option
To verify this, I created a database called Test with option CONCATENATE NULL YIELDS NULL=FALSE and a login which defaults to this database and execute the following SQL statements using SQLCMD.
set nocount on
declare #dbName sysname
select #dbName = DB_NAME()
select 'I am in database =',#dbName
select 'The CONCAT_NULL_YIELDS_NULL setting is =', is_concat_null_yields_null_on
from sys.databases
where name = #dbName
IF ( (4096 & ##options) = 4096 )
begin
select 'CONCAT_NULL_YIELDS_NULL is ON'
end
else
begin
select 'CONCAT_NULL_YIELDS_NULL is OFF'
end
go
The output of the above SQL is
I am in database = Test
is_concat_null_yields_null_on
The CONCAT_NULL_YIELDS_NULL setting is = 0
CONCAT_NULL_YIELDS_NULL is ON
Why is the CONCAT_NULL_YIELDS_NULL ON when it should have been OFF as the database Test had this option set to OFF ?
Is my interpretation of the M.S document incorrect OR is the documentation itself wrong ?
I know that this feature is marked for deprecation but my understanding is that it is still active for MS SQL2008R2.
The database options aren't very relevant because the various client libraries and tools all have their own defaults anyway which they set on your behalf at connection time.
Erland Sommarskog lists them here

INSERT failed because the following SET options have incorrect setting only in Perl Sybase

I have the following Perl script:
use strict;
use warnings;
use DBI;
my $db_connect = 'dbi:Sybase:server=10.2.2.2\CATDB;charset=utf8;database=Dev';
my $db_username = "*****";
my $db_password = "*****";
my $dbh = DBI->connect($db_connect, $db_username, $db_password,{ RaiseError => 1,
PrintError => 1,
AutoCommit => 1,
syb_chained_txn => 0,
syb_enable_utf8 => 1 } ) || die "Failed to connect to *** database: $DBI::errstr\n";
my $insertContractSQL2 = '
BEGIN
DECLARE #ContractID int
UPDATE dbo.Sequences SET NextContractID = NextContractID + 1
SET #ContractID = (SELECT NextContractID FROM dbo.Sequences)
SET ANSI_NULL_DFLT_ON, ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON
SET ANSI_NULL_DFLT_OFF, ARITHIGNORE, CURSOR_CLOSE_ON_COMMIT, IMPLICIT_TRANSACTIONS, NOCOUNT, NUMERIC_ROUNDABORT, XACT_ABORT OFF
INSERT INTO dbo.CONTRACTS
(ContractID
,modifieddate
,FranchiseID
,FamilyID
,EducatorID
,StartDate
,EndDate
,ContractTypeID
,PayRate1
,PayRate2
,PayRate3
,PayRate1Hours
,PayRate2Hours
,PayRate3Hours
,WageAdminContractorRate
,ContributionContractorRate
,WageAdminAmount
,ACCAmount
,PorseContributionAmount
,WINZSubsidyAmount
,WINZSubsidyAmountChildcareOSCAR
,ACCInvoicedPerQuarterAmount
,FamilyAPAmount
,OtherFortnightPayment
,OtherFortnightPaymentDesc
,ReferralAgencyID
,NextAppraisalDate
,NextAppraisalTypeID
,PendingApproval
,Active
,modifiedby
,BeingEdited
,MOENetworkID
,NewFlag
,ReceivedDate
,FreeECEAmount
,OptionalChargeRate
,OptionalChargeAgreement
,TerminationApproved
,AgreedDeductions
,PayRateEce
,PayRateEceHours
,PreECEClarity
,TotalOptionalCharges
,NonChildContributionAmount
,FreeECETopup
,Donation
,NonChildWinzChildcareAmount
,ManuallyTerminated
,ContractDuplicatedFlag
,CreateDate
,RosteredContractID)
VALUES (
#ContractID
,GETDATE()
,63,22901,9134,\'2014-06-03 00:00:00.0\',\'2014-06-28 00:00:00.0\',2,0,0,0,5,0,0,4.75,0,0,0,0,0,0,0,0,0,null,null,null,null,0,1,\'admin\',1,null,0,\'2014-06-10 00:00:00.0\',0,0,0,0,null,0,0,0,0,0,0,0,0,0,0,\'2014-06-03 15:30:15.037\',4)
END
';
$dbh->do($insertContractSQL2);
When it runs I get:
/usr/bin/perl test.pl
DBD::Sybase::db do failed: Server message number=1934 severity=16 state=1
line=10 server= text=INSERT failed because the
following SET options have incorrect settings: 'ANSI_NULLS,
CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING'. 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.
at test.pl line 89.
Now this is a lousy question I know. But I have run the same query via three different GUIs for SQL Server and I don't get this error. I have gone through the first 3 or 4 pages of Google results, and have gotten nowhere. Any information would be much appreciated.
Note: I assume that because the query runs in other tools that set options are correct.
Please refer this link you may need to set order to create a table with a persisted, computed column, the following connection settings must be enabled:
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET ARITHABORT ON
SET CONCAT_NULL_YIELDS_NULL ON
SET NUMERIC_ROUNDABORT ON
SET QUOTED_IDENTIFIER ON
You can set this with the $sth->do() method or with ISQL. You need to execute them first after you connect to the DB, before executing your "SELECT", "UPDATE" or any other command.
I solved it in this nasty way:
EXEC('
IF EXISTS(SELECT * FROM sysindexes WHERE Name = ''IX_GPS_XY'')
DROP INDEX [IX_GPS_XY] ON [dbo].[Cities];
')
EXEC('
INSERT INTO dbo.Cities(Name, CountyID, GPSXY)
VALUES...
')
EXEC('
IF NOT EXISTS(SELECT * FROM sysindexes WHERE Name = ''IX_GPS_XY'') BEGIN
SET ARITHABORT ON;
...
CREATE SPATIAL INDEX...
')
I ran a script generated by SQL Server studio and had the error "INSERT failed because the following SET options have incorrect settings: 'ANSI_PADDING'"
My solution is to add the keyword "GO" and the script worked.
The script with error:
--SOME INSERT STATEMENTS
SET ANSI_PADDING ON
--SOME INSERT STATEMENTS
The script that worked:
--SOME INSERT STATEMENTS
SET ANSI_PADDING ON
GO
--SOME INSERT STATEMENTS
I hope it helps.

What's the recommended configuration regarding ANSI relating settings?

I've seen many questions regarding the ANSI related settings,
and read some docs that state some features (like indexes on computed
columns and indexed views) can become worthless depending on
ANSI settings on or off...
So, what the recommended values for those:
ANSI_Padding
ANSI_NULLS
ANSI_WARNINGS
Concat_NULL_YELDS_NULL
QUOTED_IDENTIFIER
ARITHABORT
NUMERIC_ROUNDABORT
I would like guidelines regarding those.
For indexed views and indexed or persisted computed columns the following SET OPTIONS are all prescribed
SET options Required value
--------------------- -------------
ANSI_NULLS ON
ANSI_PADDING ON
ANSI_WARNINGS* ON
ARITHABORT ON
CONCAT_NULL_YIELDS_NULL ON
NUMERIC_ROUNDABORT OFF
QUOTED_IDENTIFIER ON
In SQL Server 2005 setting ANSI_WARNINGS to ON implicitly sets ARITHABORT to ON unless the database compatibility level is set to 80 or earlier (when it needs to be set explicitly).
Despite this it does make sense to be consistent in the ARITHABORT setting as this is used as a plan cache key and inconsistency can lead to duplicated plans wasting valuable plan cache space. You can see this from the query below.
SET ARITHABORT OFF
GO
SELECT * FROM master..spt_values WHERE number= -10 /*plan_cache_test*/
GO
SET ARITHABORT ON
GO
SELECT * FROM master..spt_values WHERE number= -10 /*plan_cache_test*/
GO
SELECT *
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa
CROSS APPLY sys.dm_exec_query_plan(plan_handle)
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
WHERE attribute = 'set_options' AND text LIKE '%plan_cache_test%'
AND text NOT LIKE '%this_query%'
Even without the indexed view / persisted column requirements the OFF settings are deprecated for the following optionsANSI_PADDING,ANSI_NULLS,CONCAT_NULL_YIELDS_NULL and XQuery and XML data modification statements requires that QUOTED_IDENTIFIER be ON.

Resources