Имеет ли NULL тип данных?
я столкнулся с кодом, подобным этому сегодня.
SELECT AuditDomain,
ObjectId,
AuditSubdomain = CONVERT(VARCHAR(50), NULL),
SubDomainObjectId = CONVERT(INT, NULL)
FROM Audit
это, по-видимому, означает, что информация о типе данных может быть связана с нулевым значением. Присоединяет ли это метаданные к нулевому значению, идентифицирующему его как указанный тип данных?
этот пост подробно способ найти тип данных в Sql Server, но когда я пытаюсь следующую строку, она возвращается как NULL:
SELECT CAST(SQL_VARIANT_PROPERTY(CONVERT(INT, NULL), 'BaseType') AS VARCHAR(20))
5 ответов
в SQL Server,NULL
это INT
по умолчанию во всех сценариях, которые я могу придумать. Вы можете определить это с помощью следующего кода:
SELECT x = NULL INTO #x;
EXEC tempdb..sp_columns '#x';
результаты:
TABLE_QUALIFIER TABLE_OWNER TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME
--------------- ----------- ---------- ----------- --------- ---------
tempdb dbo #x___... x 4 int
прежде чем вы поместите его в таблицу или иным образом свяжете его с некоторыми контекстными метаданными, что это вам даст? Какая разница это INT
или DATETIME
или что-то еще? Что вы будете делать с этой информацией?
SQL_VARIANT_PROPERTY
возвращает NULL
потому что он, похоже, требует обоих метаданных и значение, чтобы быть значимым. Наблюдайте (используя другой тип, чтобы просто смешать его):
SELECT SQL_VARIANT_PROPERTY(NULL, 'BaseType');
DECLARE @x DATE;
SELECT SQL_VARIANT_PROPERTY(@x, 'BaseType');
DECLARE @y DATE = SYSDATETIME();
SELECT SQL_VARIANT_PROPERTY(@y, 'BaseType');
результаты:
NULL
NULL
date
таким образом, кажется, нужны оба типа и значение для точного определения базового типа.
Что касается того, почему это работает именно так,пожав. Вы должны спросить людей с доступом к исходному коду.
отметим, что NULL
только примите базовый тип, когда вы принудили руку SQL Server: вы создали таблицу на его основе. Вполне возможно, что SQL Server вернет ошибку в этой ситуации (и на самом деле во многих ситуациях, когда он должен угадать, какой тип данных вы имели в виду). Способ избежать этого-не создавать ситуации, когда SQL Server должен угадать (поэтому я спросил, что вы будете делать с этой информацией?).
Null не имеет типа данных. Целью null является представление "неизвестного" как по значению, так и по типу.
ISNULL () возвращает тип данных для первого аргумента с типом данных, представленным ему.
Я знаю, что у вас уже есть хорошие ответы, но SQL_VARIANT_PROPERTY я думаю, что был неправильно понят.
вы используете sql_variant_property со столбцом, а затем указываете, что вы хотите на его свойство метаданных. Однако если это нуль не говорит.
например:
declare
@Start date = getdate()
, @End datetime= getdate()
, @Int int = 1
, @DateNull date
;
select
sql_variant_property(@Start, 'BaseType')
, sql_variant_property(@End, 'BaseType')
, sql_variant_property(@Int, 'BaseType')
, sql_variant_property(@DateNull, 'BaseType')
вернет три типа данных и значение null. Обработка NULL является большой частью SQL. Очень многие люди, включая меня, иногда хотят обрабатывать null со значением для представляйте его или в другое время не заботьтесь. SQL Variant работает только для заполненного значения с аргументом: "BaseType", иначе он вернет значение null. Насколько я знаю, это связано с тем, что SQL говорит: "У вас нет данных здесь, нечего определять для использования памяти."
обычно я буду указывать isnull (@thing, 0) при работе с целыми числами, если я явно хочу, чтобы набор данных включал нули для неизвестных. В других случаях я могу пожелать, чтобы пользователь знал, что нулевое вхождение сделало что-то еще isnull (@thing, 'not present') для отчета. В других случаях вы можете использовать coalesce для объединения массива возможностей (@thing, @otherthing, @yetotherthing, 'unknown').
Я думаю, что в коде, который вы видите, кто-то преобразует что-то, когда я не уверен, где вам действительно нужно это сделать. Тип данных столбца в таблице поддерживается таким, каким он должен быть, и SQL не будет хранить в нем память, если она равна NULL. Так что нужно это изменить. кажется произвольным ИМХО. Я знаю, что вы можете обрабатывать лучшее потребление памяти, когда вы ожидаете больше нулей с разреженной опцией, которая была введена я верю в SQL 2008. Но я не знаю, когда бросить что-то, что почти ничего не потребляет, чтобы быть больше.
couse NULL имеет тип данных. Попробуйте следующий код для подтверждения:
SELECT
CAST(NULL AS date) AS c1,
CAST(NULL AS time) AS c2
INTO #x;
EXEC tempdb..sp_columns '#x';
и я думаю, что в реализации SQL_VARIANT есть ошибка, потому что она теряет информацию о типе NULL. Очень жаль!
Я не согласен с @aaron-bertrand. Поскольку по умолчанию SQl server создал столбец с целочисленным типом данных для хранения значения NULL как Null, его можно вставить в int, Datetime, Date, Varchar любой другой столбец.
при вставке Null в таблицу с Выберите x = NULL в #x;
SQl server создал столбец целочисленного типа по умолчанию, так как Null может быть вставлен в столбец Integer.
так может быть из-за характера запроса, который мы написали "Выберите x = NULL в #x;", что делает столбец целым числом и помещает значение NULL.