I find the documentation, blog posts, Stackoverflow answers unhelpful in explaining what turning on QUOTED_IDENTIFIER
means.
Olden times
Originally, SQL Server allowed you to use quotation marks ("..."
) and apostrophes ('...'
) around strings interchangeably (like Javascript does):
SELECT "Hello, world!"
--quotation mark
SELECT 'Hello, world!'
--apostrophe
And if you wanted a name table, view, procedure, column etc with something that would otherwise violate all the rules of naming objects, you could wrap it in square brackets ([
, ]
):
CREATE TABLE [The world's most awful table name] (
[Hello, world!] int
)
SELECT [Hello, world!] FROM [The world's most awful table name]
And that all worked, and made sense.
Then came ANSI
Then ANSI came along and had other ideas:
- use apostrophe (
'...'
) for strings
- if you have a funky name, wrap it in quotation marks (
"..."
)
- and we don't even care about your square brackets
Which means that if you wanted to "quote" a funky column or table name you must use quotation marks:
SELECT "Hello, world!" FROM "The world's most awful table name"
If you knew SQL Server, you knew that quotation marks were already being used to represent strings. If you blindly tried to execute that ANSI-SQL as if it were T-SQL, it is nonsense:
SELECT 'Hello, world!' FROM 'The world''s most awful table name'
and SQL Server tells you so:
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near 'The world's most awful table name'.
You must opt-in to the new ANSI behavior
So Microsoft added a feature to let you opt-in to the ANSI flavor of SQL.
Original (aka SET QUOTED_IDENTIFIER OFF)
SELECT "Hello, world!" --valid
SELECT 'Hello, world!' --valid
SET QUOTED_IDENTIFIER ON
SELECT "Hello, world!" --INVALID
SELECT 'Hello, world!' --valid
These days everyone has SET QUOTED_IDENTIFIERS ON
, which technically means you should be using quotes
rather than square brackets
around identifiers:
T-SQL (bad?) (e.g. SQL generated by Entity Framework)
UPDATE [dbo].[Customers]
SET [FirstName] = N'Ian'
WHERE [CustomerID] = 7
ANSI-SQL (good?)
UPDATE "dbo"."Customers"
SET "FirstName" = N'Ian'
WHERE "CustomerID" = 7
In reality nobody in the SQL Server universe uses U+0022 QUOTATION MARK " to wrap identifiers. We all continue to use [].