Имеет ли 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 () возвращает тип данных для первого аргумента с типом данных, представленным ему.

http://msdn.microsoft.com/en-us/library/ms187928.aspx


Я знаю, что у вас уже есть хорошие ответы, но 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.