ANSI NULLS и QUOTED IDENTIFIER убивали вещи. Для чего они?
примечание: Я проверил понимание значение параметра и это не ответ на мой вопрос.
Я получил мои DBAs для запуска индекса, который я сделал на моих серверах Prod (они просмотрели его и одобрили).
это ускорило мои запросы, как я и хотел. Однако я начал получать такие ошибки:
как разработчик я обычно игнорировал эти настройки. И это никогда не имело значения. (За 9+ лет). Ну, сегодня это важно.
Я пошел и посмотрел на один из sprocs, которые терпят неудачу, и у него есть это перед созданием для sproc:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
может ли кто-нибудь сказать мне с точки зрения разработчика приложений, что делают эти операторы set? (просто добавление вышеуказанного кода перед моими инструкциями Index create не устранило проблему.)
Примечание: вот пример того, как выглядели мои индексы:
CREATE NONCLUSTERED INDEX [ix_ClientFilerTo0]
ON [ClientTable] ([Client])
INCLUDE ([ClientCol1],[ClientCol2],[ClientCol3] ... Many more columns)
WHERE Client = 0
CREATE NONCLUSTERED INDEX [IX_Client_Status]
ON [OrderTable] ([Client],[Status])
INCLUDE ([OrderCol1],[OrderCol2],[OrderCol3],[OrderCol4])
WHERE [Status] <= 7
GO
4 ответов
OK, с точки зрения разработчика приложений, вот что делают эти настройки:
значение параметра
этот параметр управляет тем, как кавычки ".."
интерпретируются компилятором SQL. Когда QUOTED_IDENTIFIER
включено, тогда кавычки рассматриваются как скобки ([...]
) и может использоваться для цитирования имен объектов SQL, таких как имена таблиц, имена столбцов и т. д. Когда он выключен (не рекомендуется), кавычки обрабатываются как апострофы ('..'
) и может использоваться для цитаты текстовые строки в командах SQL.
параметр ansi_nulls
этот параметр управляет тем, что происходит при попытке использовать любой оператор сравнения, кроме IS
on NULL. Когда он включен, эти сравнения следуют стандарту, который говорит, что сравнение с NULL всегда терпит неудачу (потому что это не значение, Это флаг) и возвращает FALSE
. Когда этот параметр выключен (действительно не рекомендуется) вы можете успешно рассматривать его как значение и использовать =
, <>
, etc. на нем и вернись как можно скорее.
правильный способ справиться с этим-это использовать IS
(ColumnValue IS NULL ..
).
параметр concat_null_yields_null
этот параметр определяет, будут ли NULLs "Propogate" whn использоваться в строковых выражениях. Когда этот параметр включен, он следует стандарту и выражению типа 'some string' + NULL ..
всегда возвращает NULL. Таким образом, в серии конкатенаций строк один NULL может привести к возвращению всего выражения NULL. Отключение этого (также не рекомендуется) приведет к тому, что нули будут рассматриваться как пустые строки, поэтому 'some string' + NULL
просто оценивает в 'some string'
.
правильный способ справиться с этим - с помощью функции COALESCE (или ISNULL):'some string' + COALESCE(NULL, '') ..
.
найти документация, блога, и StackOverflow ответы бесполезно объяснять, что включается QUOTED_IDENTIFIER
средства.
былые времена
первоначально SQL Server разрешал использовать кавычки ("..."
) и Апостроф ('...'
) вокруг строк взаимозаменяемо (как это делает Javascript):
-
SELECT "Hello, world!"
--цитата Марк!--38--> -
SELECT 'Hello, world!'
--Апостроф
и если вам нужна таблица имен, представление, процедура, столбец и т. д. С чем-то, что в противном случае нарушило бы все правила именования объектов, вы можете обернуть его в квадратные скобки ([
, ]
):
CREATE TABLE [The world's most awful table name] (
[Hello, world!] int
)
SELECT [Hello, world!] FROM [The world's most awful table name]
и все это работало, и имело смысл.
пришел в ANSIзатем Анси и другие идеи:
- если у вас есть фанк имя, оберните его в кавычки (
"..."
) - использовать Апостроф (
'...'
) для строк - и мы даже не заботимся о ваших квадратных скобках
что означает, что если вы хотите "цитата" фанки имя столбца или таблицы вы должны использовать кавычки:
SELECT "Hello, world!" FROM "The world's most awful table name"
если вы знали SQL Server, вы знали, что цитата Маркс!--31--> уже использовались для представления строк. Если вы слепо пытались выполнить это В ANSI-SQL В как будто T-SQL: это ерунда, и SQL Server сказал вам так:
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near 'The world's most awful table name'.
вы должны выбрать новое поведение ANSI
таким образом, Microsoft добавила функцию, чтобы позволить вам выбрать в ANSI вкус SQL.
Оригинал
SELECT "Hello, world!" --valid
SELECT 'Hello, world!' --valid
УСТАНОВИТЬ QUOTED_IDENTIFIER ON
SELECT "Hello, world!" --INVALID
SELECT 'Hello, world!' --valid
в наши дни у всех есть SET QUOTED_IDENTIFIERS ON
, который технически означает, что вы должны использовать quotes
, а не square brackets
вокруг идентификаторов:
T-SQL (плохо?) (например, SQL, созданный Entity Framework)
UPDATE [dbo].[Customers]
SET [FirstName] = N'Ian'
WHERE [CustomerID] = 7
ANSI-SQL (хорошо?)
UPDATE "dbo"."Customers"
SET "FirstName" = N'Ian'
WHERE "CustomerID" = 7
Я думаю, что при перестройке индексов он был выключен.
проверьте установите параметры с их значениями настроек, требуемыми при работе с фильтрованным индексом
при работе с фильтрованным индексом необходимо включить нижеприведенную настройку:
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET ARITHABORT ON
SET CONCAT_NULL_YIELDS_NULL ON
SET QUOTED_IDENTIFIER ON
вам нужно добавить, чтобы добавить
SET ANSI_NULLS, QUOTED_IDENTIFIER ON
для всех моих хранимых процедур редактирование таблицы с вычисляемым столбцом, чтобы избежать этого ошибка.
когда SET ANSI_NULLS включен, оператор SELECT, который использует WHERE column_name = NULL возвращает нулевые строки, даже если в имя столбца. Инструкция SELECT, использующая WHERE column_name NULL возвращает нулевые строки, даже если в column_name есть значения nonnull.
когда SET ANSI_NULLS выключен, равно ( = ) и не равно () операторы сравнения не следуют стандарт ISO. ОТБОР оператор, использующий WHERE column_name = NULL возвращает строки, которые имеют значения null в column_name. Инструкция SELECT, использующая WHERE column_name NULL возвращает строки, которые имеют значения nonnull в колонна. Кроме того, оператор SELECT, который использует WHERE column_name Возвращает XYZ_value всех строк, которые не XYZ_value и что не НОЛЬ.
при установке QUOTED_IDENTIFIER включен, идентификаторы могут быть разделены двойные кавычки, и литералы должны быть заключены в одинарные кавычки. Когда SET QUOTED_IDENTIFIER выключен, идентификаторы не могут быть в кавычках и должен следовать всем правилам Transact-SQL для идентификаторов. Для дополнительные сведения см. В разделе идентификаторы базы данных. Литералы могут быть разделены одинарными или двойными кавычками.
когда SET QUOTED_IDENTIFIER включен (по умолчанию), все строки разделены двойная цитата метки интерпретируются как идентификаторы объектов. Таким образом кавычки идентификаторы не должны следовать Transact-SQL правила для идентификаторов. Они могут быть зарезервированы ключевые слова и могут включать символы, не разрешенные в языке Transact-SQL для идентификаторов. Двойной кавычки нельзя использовать для разграничения строковых выражений; одинарные кавычки должны использоваться для заключения символьных строк. Если одинарная кавычка ( ' ) является частью литеральной строки, она может быть представлены два один кавычки.)"( УСТАНОВИТЬ ЗНАЧЕНИЕ ПАРАМЕТРА должен быть включен, когда зарезервированные ключевые слова используются для имен объектов в база данных.
параметр concat_null_yields_null
когда SET CONCAT_NULL_YIELDS_NULL включен, объединение нулевого значения с помощью строки получается нулевой результат. Например, выберите ' abc ' + NULL дает NULL. Когда SET CONCAT_NULL_YIELDS_NULL выключен, объединение значения null со строкой дает саму строку (значение null обрабатывается как пустая строка). Например, выберите " abc " + null выходы азбука.
Если SET CONCAT_NULL_YIELDS_NULL не указан, то настройка Применяется параметр базы данных CONCAT_NULL_YIELDS_NULL.
ANSI_NULLS ON делает любое двоичное логическое выражение с нулевым значением равным false. Используя следующий шаблон:
declare @varA, @varB int
if <binary boolean expression>
begin
print 'true'
end
else
begin
print 'false'
end
@varA: NULL; @varB: NULL; @varA = @varB evaluates to false
@varA: 1; @varB: NULL; @varA <> @varB evaluates to false
правильный способ проверить значение null-использовать is [not] NULL
@varA: NULL; @varA is NULL evaluates to true
@varA: 1; @varA is not NULL evaluates to true
QUOTED_IDENTIFER ON просто позволяет использовать двойные кавычки для разграничения идентификаторов (плохая идея IMO, просто квадратные скобки пользователя)
from tblA "a" -- ok when ON, not ok when OFF
from tblA [a] -- always ok