ANSI_NULLS and QUOTED_IDENTIFIER killed things. What are they for?

后端 未结 4 573
北海茫月
北海茫月 2020-12-24 02:43

NOTE: I checked Understanding QUOTED_IDENTIFIER and it does not answer my question.

I got my DBAs to run an index I made on my Prod servers (they looked it over and

4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-24 03:05

    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:

    • if you have a funky name, wrap it in quotation marks ("...")
    • use apostrophe ('...') for strings
    • 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, it is the same as trying to execute:

    SELECT 'Hello, world!' FROM 'The world''s most awful table name'
    

    as though it were T-SQL: it's nonsense, 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
    

提交回复
热议问题