"SYSNAME
не может быть NULL
" просто не соответствует действительности.Ответ на связанный вопрос является правильным, когда он говорит, что он эквивалентен NVARCHAR(128) NOT NULL
как по умолчанию - и затем эффективно только в определениях столбцов.Сравните:
-- When not specified, columns are NULL
SET ANSI_NULL_DFLT_ON ON
-- Works
CREATE TABLE T(N NVARCHAR(128)); INSERT T DEFAULT VALUES; SELECT * FROM T
GO
DROP TABLE T
GO
-- When not specified, columns are NOT NULL
SET ANSI_NULL_DFLT_ON OFF
-- Error: can't insert NULL
CREATE TABLE T(N NVARCHAR(128)); INSERT T DEFAULT VALUES; SELECT * FROM T
GO
DROP TABLE T
GO
А теперь попробуйте то же самое с SYSNAME
:
-- When not specified, columns are NULL
SET ANSI_NULL_DFLT_ON ON
-- Error: SYSNAME is NOT NULL, regardless of defaults
CREATE TABLE T(N SYSNAME); INSERT T DEFAULT VALUES; SELECT * FROM T
GO
DROP TABLE T
GO
Но это не значит, что SYSNAME
не может быть NULL
, все, что нам нужно сделать, этоскажем, что это может быть:
-- Works
CREATE TABLE T(N SYSNAME NULL); INSERT T DEFAULT VALUES; SELECT * FROM T
GO
DROP TABLE T
GO
Практически во всех других контекстах, где используется тип (переменные, параметры хранимой процедуры), мы не можем указывать значения NULL
или NOT NULL
и NULL
, которые всегда разрешенытак что эти NOT NULL
метаданные очень редко актуальны.Не случайно в приведенном выше коде используются обычные таблицы: если вы попробуете то же самое с табличной переменной, вы обнаружите, что ANSI_NULL_DFLT_ON
игнорируется и NULL
всегда используется по умолчанию для столбцов, если не указано, поэтомутолько соответствующие случаи:
-- Can't insert NULL
DECLARE @T TABLE (N SYSNAME); INSERT @T DEFAULT VALUES; SELECT * FROM T@
GO
-- OK
DECLARE @T TABLE (N SYSNAME NULL); INSERT @T DEFAULT VALUES; SELECT * FROM @T
GO