SQL Server - Using Quoted Identifier ON and OFF and Getdate() - sql-server

I have a problem with my script SQL, please help me.
Ex:
I have a insert statments:
INSERT INTO CUSTOMER (Code, Date) VALUES (1, GETDATE());
When I execute this insert, retuns the follow message:
"Msg 1934, Level 16, State 1, Server
HENRIQUE-PC, Line 5 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 notificatio ns
and/or XML data type methods and/or
spatial index operations.".
Now, when I used SET QUOTED_IDENTIFIER ON, my insert is executed with success.
Ex:
SET QUOTED_IDENTIFIER OFF
GO
INSERT INTO CUSTOMER (Code, Date) VALUES (1, GETDATE());
SET QUOTED_IDENTIFIER ON
GO
(1 row(s) affected)
What relationship betwhen GETDATE() and QUOTED IDENTIFIER?
Why I need to use QUOTED IDENTIFIER in this case?
I believe it is because of getdate. Why?
Thanks.
Henrique Melicio

Henrique,
The reason you're getting that error is not related to GETDATE(), it has to do with indexes on columns from your CUSTOMER table. This bit from SQL Server 2008's SET Statements (Transact-SQL) document explains the issue in more detail:
When you are creating and manipulating
indexes on computed columns or indexed
views, the SET options ARITHABORT,
CONCAT_NULL_YIELDS_NULL,
QUOTED_IDENTIFIER, ANSI_NULLS,
ANSI_PADDING, and ANSI_WARNINGS must
be set to ON. The option
NUMERIC_ROUNDABORT must be set to OFF.
If any one of these options is not set
to the required values, INSERT,
UPDATE, DELETE, DBCC CHECKDB and DBCC
CHECKTABLE actions on indexed views or
tables with indexes on computed
columns will fail. SQL Server will
raise an error listing all the options
that are incorrectly set. Also, SQL
Server will process SELECT statements
on these tables or indexed views as if
the indexes on computed columns or on
the views do not exist.

Related

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?

ANSI Warnings on Amazon RDS SQL Server not setting

I have strange problem in an AWS RDS SQL Server database I have spun up and I can't figure out what is going on.
Test 1
create table #tmp
(test varchar(10) null)
insert into #tmp
select 'asfsadfasdsafdafas'
select * from #tmp
drop table #tmp
Results in:
Msg 8152, Level 16, State 14, Line 5
String or binary data would be truncated.
(0 row(s) affected)
Test 2
set ANSI_WARNINGS OFF
create table #tmp1
(test varchar(10) null)
insert into #tmp1
select 'asfsadfasdsafdafas'
select * from #tmp1
drop table #tmp1
Results in:
------------------
asfsadfasd
When I look at the database properties it says that ANSI Warnings Enabled is set to FALSE, however, the database does not appear to be behaving as expected.
Any help would be appreciated.
EDIT:
Another Example might help
ALTER DATABASE test_db
set QUOTED_IDENTIFIER OFF
go
select "hello"
Results in:
Msg 207, Level 16, State 1, Line 5
Invalid column name 'hello'.
Thanks
--The Issue Occur Because of Length Of Datatype
create table #tmp1
(test varchar(50) null)
insert into #tmp1
select 'asfsadfasdsafdafas'
select * from #tmp1
drop table #tmp1
--==============================
When create or alter SQL object like Stored Procedure, User Defined Function in Query Analyzer, it is created with following SQL commands prefixed and suffixed. What are these – QUOTED_IDENTIFIER ON/OFF and ANSI_NULL ON/OFF?
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO--SQL PROCEDURE, SQL FUNCTIONS, SQL OBJECTGO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
ANSI NULL ON/OFF:
This option specifies the setting for ANSI NULL comparisons. When this is on, any query that compares a value with a null returns a 0. When off, any query that compares a value with a null returns a null value.
QUOTED IDENTIFIER ON/OFF:
This options specifies the setting for usage of double quotation. When this is on, double quotation mark is used as part of the SQL Server identifier (object name). This can be useful in situations in which identifiers are also SQL Server reserved words.

Collation conflict using except SQL Server

I am trying to execute the following query on two different databases with difent collations
select * from sourcedb.DBO.PKtable
except
select * from destinationdb.DBO.PKtable
It is clear that both the tables have the same columns and the primary key
But when executing, encountered the following exception
Msg 468, Level 16, State 9, Line 17
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CS_AS" in the EXCEPT operation.
I cannot use COLLATE keyword because.. I will be using the above query at runtime and the table name and columns vary, hence cannot predict the columns of the table.
I have tried to change the collation of the destination database to same as the source database using the following command
ALTER DATABASE destinationDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE destinationDB COLLATE <<sourceCollation>>;
ALTER DATABASE destinationDB SET MULTI_USER
The collation is set to the database and I can see it from the sys tables.
Even then when I execute the query mentioned above, getting the same error
EDIT1: Basically I'm trying to get the records which have the same primary key but difference in the row.
Another possible workaround (apart from dynamic sql) might be to use a temporary table. (This may suit if this is a one off type of operation).
-- create empty #PKTable with required columns and collation.
select * INTO #PKTable from sourcedb.DBO.PKtable where 1=0
-- fill table with data
insert #PKTable select * from destinationdb.DBO.PKtable
-- compare
select * from sourcedb.DBO.PKtable
except
select * from #PKTable
-- remove temp table
drop table #PKTable

Scope of SET ANSI_WARNINGS OFF

if I have SET ANSI_WARNINGS OFF in one stored procedure to get rid of a warning, it only takes effects of that stored procedure and has no impact on other ones, which means in other stored procedures, the ANSI_WARNINGS is still on.
What if I want to turn it off for all stored procedures?
Why it is default on? How could I know that?
Do other settings(e.g., NOCOUNT) in sql server work the same way?
Thanks a lot.
It will be great if anybody can share articles about common characteristics of these settings with me.
It's possibly worth point out that not only does it NOT affect other stored procedures, it only affects statements following the SET operation
e.g. run this and you will see that the option is turned off then on and then off again.
CREATE TABLE test
(
intvalue int NULL
)
INSERT INTO test VALUES (1)
INSERT INTO test VALUES (NULL)
SET ANSI_WARNINGS OFF
SELECT COUNT(intvalue) FROM test
-- (1 row(s) affected)
SET ANSI_WARNINGS ON
SELECT COUNT(intvalue) FROM test
-- (1 row(s) affected)
-- Warning: Null value is eliminated by an aggregate or other SET operation.
SET ANSI_WARNINGS OFF
SELECT COUNT(intvalue) FROM test
-- (1 row(s) affected)
DROP TABLE test
From BOL:
SQL Server includes the ANSI_WARNINGS database option. This is
equivalent to SET ANSI_WARNINGS. When SET ANSI_WARNINGS is ON, errors
or warnings are raised in divide-by-zero, string too large for
database column, and other similar errors. When SET ANSI_WARNINGS is
OFF, these errors and warnings are not raised. The default value in
the model database for SET ANSI_WARNINGS is OFF. If not specified, the
setting of ANSI_WARNINGS applies. If SET ANSI_WARNINGS is OFF, SQL
Server uses the value of the is_ansi_warnings_on column in the
sys.databases catalog view.
You can read about it in BOL (F1 in Management Studio) or on MSDN http://msdn.microsoft.com/en-us/library/ms190368.aspx
NOCOUNT works the same.

Import from Access to SQL Server works only for first table in set

I am trying to import MsAccess 2007 data into an SQL Server database. This worked earlier, same code, same machine, except SQL Server Express 2005. After some unrelated problems, I converted to 2008 and now I am having trouble loading the data.
It's VBA code running in Access, first executes a stored procedure named ClearDB, which wipes every table. That still works. Then it loops around through all the tables, maintaining a specific order due to relationship constraints. For each table, the code executes the following three queries:
SET IDENTITY_INSERT TableOfZones ON
INSERT INTO dbo_TableOfZones SELECT Jet_TableOfZones.* FROM Jet_TableOfZones
SET IDENTITY_INSERT TableOfZones OFF
The IDENTITY_INSERT queries are pass-through, the Insert is local. This has recently started working only for the first table, then it crashes claiming that none of the records were inserted due to key violations. It's always the first table that works, regardless of which table that is, as long as it isn't one that requires matching records from another table to already be in place. Sounds like a perfectly normal screw-up in indexing or such, except that if I let it sit for a while (10-15 minutes) it suddenly works again, for one table. That Insert works, then it bombs on the next one. Again, if I let it sit for a while, that next one will suddenly work and crash on the one after that.
I have to use the IDENTITY_INSERT option, since I am importing existing data with relationships already created, else I would simply let SQL Server generate its own ID columns.
Here's the latest try:
SET IDENTITY_INSERT TableOfZones ON
INSERT INTO dbo_TableOfZones(ZoneAutoID, Zone) SELECT Jet_TableOfZones.ZoneAutoID, Jet_TableOfZones.Zone FROM Jet_TableOfZones 119
SET IDENTITY_INSERT TableOfZones OFF
119 119 0
SET IDENTITY_INSERT TableOfSystems ON
INSERT INTO dbo_TableOfSystems(SystemAutoID, System) SELECT Jet_TableOfSystems.SystemAutoID, Jet_TableOfSystems.System FROM Jet_TableOfSystems 0
SET IDENTITY_INSERT TableOfSystems OFF
221 0 221
Same results, first insert works fine, second one bombs. The first number is the record count in the source table, the second is the record count of the destination table, AFTER executing the Insert query, the third is simply the difference between the two.
In SQL Server 2008, in order to use IDENTITY INSERT you need to specify an explicit field list in both your select and your insert, i.e.:
SET IDENTITY_INSERT TableOfZones ON
INSERT INTO dbo_TableOfZones (
ID_Field,
field1,
field2,
field3...)
SELECT Jet_TableOfZones.IDField,
Jet_TableOfZones.field1,
Jet_TableOfZones.field2,
Jet_TableOfZones.field3...
FROM Jet_TableOfZones
SET IDENTITY_INSERT TableOfZones OFF
I would imagine that connections from Access would be subject to the same constraints.
Okay, this looks like better method. Sorry about the soup in the comments. Here's a copy of the commands sent out this time. I wonder if maybe I have to name the source table for each field? I'll give that a try...
SET IDENTITY_INSERT TableOfZones ON
INSERT INTO dbo_TableOfZones(ZoneAutoID, Zone) SELECT ZoneAutoID, Zone FROM Jet_TableOfZones 119
SET IDENTITY_INSERT TableOfZones OFF
119 119 0
SET IDENTITY_INSERT TableOfSystems ON
INSERT INTO dbo_TableOfSystems(SystemAutoID, System) SELECT SystemAutoID, System FROM Jet_TableOfSystems 0
SET IDENTITY_INSERT TableOfSystems OFF
221 0 221

Resources