Min*_*ica 8 t-sql sql-server ssms azure-sql-database
我有一个像这样的存储过程:
select
TransactionDate
from
(select
cast(TransactionDate as Date) as TransactionDate
from RetailTransaction) t
Run Code Online (Sandbox Code Playgroud)
但是,这使得TransactionDate
外部选择的RetailTransaction.TransactionDate
列可以为空,而列不为空.
RetailTransaction.TransactionDate
定义/设计:
内部选择:
外选择:
即使在添加isnull
或coalesce
SQL Server/SSMS之后仍然显示外部选择TransactionDate
列仍然可以为空.
select
TransactionDate
from
(select
isnull(cast(TransactionDate as Date), getdate()) as TransactionDate
from
RetailTransaction) t
Run Code Online (Sandbox Code Playgroud)
如何使TransactionDate
列不可为空?
请注意,该数据库位于Azure上,兼容级别为100(SQL Server 2008).
编辑:
isnull
在外部选择上添加仍然使列可以为外部嵌套查询:
阅读您的评论后,我做了一些挖掘和测试,即使我找不到有关它的官方文档,您是正确的,并且转换为日期使得该值可以为空,即使日期时间不可为空。我什至尝试了一种不同的方法来datetimefromparts
创建日期数据类型,但这也改变了结果的可为空性。
所以在我看来,你有两个选择:
第一个选项是向表中添加一个持久计算列,该列将保存事务日期的日期值。它必须被持久化为不可空:
ALTER TABLE RetailTransaction
ADD TransactionDateOnly AS CAST(TransactionDate As Date) PERSISTED NOT NULL;
Run Code Online (Sandbox Code Playgroud)
然后你的查询看起来像这样:
SELECT TransactionDateOnly as TransactionDate
FROM RetailTransaction
Run Code Online (Sandbox Code Playgroud)
另一种选择是声明一个具有不可空日期列的表变量,将转换结果选择到其中,然后从表变量中进行选择:
DECLARE @Target AS TABLE
(
TransactionDate Date NOT NULL
)
INSERT INTO @Target(TransactionDate)
SELECT CAST(TransactionDate as Date)
FROM RetailTransaction) t
Run Code Online (Sandbox Code Playgroud)
然后你的选择看起来像这样:
SELECT TransactionDate
FROM @Target
Run Code Online (Sandbox Code Playgroud)
这两种方法都会得到一个不可为空的日期,但我认为持久计算列选项可能会在选择上产生更好的性能,因为它不需要额外的插入...选择。