SQL Server Преобразование даты в дату без нуля - PullRequest
0 голосов
/ 04 января 2019

У меня есть хранимая процедура следующим образом:

select 
    TransactionDate 
from 
    (select 
         cast(TransactionDate as Date) as TransactionDate
     from RetailTransaction) t

Однако это делает столбец TransactionDate внешнего выбора обнуляемым, в то время как столбец RetailTransaction.TransactionDate не равен нулю.

RetailTransaction.TransactionDate определение / дизайн:

enter image description here

Внутренний выбор:

Inner Select

Внешний выбор:

Outer Select

Даже после добавления isnull или coalesce SQL Server / SSMS по-прежнему показывает, что внешний столбец выбирает TransactionDateвсе еще обнуляется.

select 
    TransactionDate 
from 
    (select 
         isnull(cast(TransactionDate as Date), getdate()) as TransactionDate
     from 
         RetailTransaction) t

Example 2

Как сделать столбец TransactionDate не обнуляемым?

Обратите внимание, что база данныхв Azure с уровнем совместимости 100 (SQL Server 2008).

РЕДАКТИРОВАТЬ:

Добавление isnull во внешний выбор все еще делает столбец обнуляемым для внешнего вложенного запроса:

outer-nested-query

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Хитрость заключается в том, чтобы поместить ISNULL во внешний запрос и добавить псевдоним, чтобы вы не потеряли имя

select 
    isnull(TransactionDate, GETDATE()) as TransactionDate
from ( 
    select 
        Cast(TransactionDate as Date) as TransactionDate
    from RetailTransaction
) t

Таким образом, SQL поймет, что поле не может быть пустым.Это должно приятно сообщить любому ORM, что это поле не должно отображаться в обнуляемый тип.

0 голосов
/ 15 января 2019

После прочтения вашего комментария я провел некоторое копание и тестирование, и хотя я не смог найти официальную документацию по этому поводу, вы правы, и приведение к дате делает значение обнуляемым, даже если дата и время не обнуляются.Я даже попробовал другой метод, используя datetimefromparts для создания типа данных даты, но это также изменяет обнуляемость результата.
Так что, как я вижу, у вас есть два варианта:

Первый вариант - добавить в таблицу постоянный вычисляемый столбец, который будет содержать значение даты даты транзакции.Это должно быть сохранено, чтобы быть не обнуляемым:

ALTER TABLE RetailTransaction
    ADD TransactionDateOnly AS CAST(TransactionDate As Date) PERSISTED NOT NULL;

, и тогда ваш запрос будет выглядеть так:

SELECT TransactionDateOnly as TransactionDate
FROM RetailTransaction

Другой вариант - объявить переменную таблицы с ненулевым значением.Обнуляемый столбец даты, выберите результаты приведения в него, а затем выберите из табличной переменной:

DECLARE @Target AS TABLE
(
    TransactionDate Date NOT NULL
)
INSERT INTO @Target(TransactionDate)
SELECT CAST(TransactionDate as Date) 
FROM RetailTransaction) t

И тогда ваш выбор будет выглядеть следующим образом:

SELECT TransactionDate 
FROM  @Target

В обоих случаях вы получитев результате необнуляемая дата, но я думаю, что опция сохраняемого вычисляемого столбца, вероятно, должна дать лучшую производительность для выбора, потому что он не требует дополнительной вставки ... выбора.

0 голосов
/ 04 января 2019

Да, причина, по которой он отображает Nullable для необнуляемого столбца, заключается в том, что вы выбираете внешний выбор как вычисленный на основе условий isnull и других.

В этой таблице «Электронная почта» не является столбцом, который можно обнулять, и теперь, если я задаю условие Иснулла во внутреннем запросе, оно будет выглядеть следующим образом.

enter image description here

Теперь, если я не предоставлю никаких условий, это будет так.

enter image description here

Вы также можете обратиться к этой ссылке для подробного объяснения.

https://dba.stackexchange.com/questions/114260/why-is-a-not-null-computed-column-considered-nullable-in-a-view

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...