为啥当我使用 IIF 时,我的表中的某些行而不是其他行的日期转换失败

Posted

技术标签:

【中文标题】为啥当我使用 IIF 时,我的表中的某些行而不是其他行的日期转换失败【英文标题】:Why does this conversion to date fail on some rows in my table and not other rows when I use an IIF为什么当我使用 IIF 时,我的表中的某些行而不是其他行的日期转换失败 【发布时间】:2021-12-23 04:42:39 【问题描述】:

我有这张表和数据:

CREATE TABLE dbo.tBadDate
(
  BadDateID    int NOT NULL,
  StartDate    nchar(20) NULL,
  CONSTRAINT [PK_tBadDate] PRIMARY KEY CLUSTERED 
  (
    [BadDateID] ASC
  )
);

INSERT dbo.tBadDate (BadDateID, StartDate) VALUES 
(1, N'1/1/2020            '),
(2, N'Jan 1 2021          '),
(3, N'January 1 2021      '),
(4, N'Ja 1 2021           '),
(5, N'Jan,1,2021          '),
(6, N'2021.1.1            '),
(7, N'8/8/1981            '),
(8, NULL),
(9, N'January First, 2021 ');

此脚本有效:

SELECT StartDate, ISDATE(StartDate) from tBadDate;

此脚本失败:

SELECT StartDate, IIF(ISDATE(StartDate) = 1 , CONVERT(DATE, 
  startDate), 'Undefined Format') 
  FROM tBadDate

消息 241,级别 16,状态 1 从字符串转换日期和/或时间时转换失败。

【问题讨论】:

您的 IIF 返回 varchar 或日期。由于一列只能有一种数据类型,因此尝试将 varchar 值 'Undefined Format' 转换为日期。即便如此,这些不同的格式不太可能使用单个CONVERT 进行转换,您需要针对不同的格式使用不同的样式。 为什么首先将日期(和时间)值存储为varchar,为什么它们每次都采用不同的格式? 那里是你的问题。修复您的设计;有 6 种日期和时间数据类型,其中 5 种是无限更好的数据类型选择。 @nicomp ISDATE(和ISNUMERIC)不是很好的功能;两者都可能给出误报/否定,因为它们检查值是否可以转换为至少一种相关数据类型(但这并不意味着它可以转换为您要转换的数据类型值)。 TRY_CONVERTTRY_CAST明显更好的选择。但是,再一次,BEST™ 解决方案是:修复您的设计。 " 我可以选择回滚编辑。" 这并不意味着您应该这样做。停止在问题中添加噪音并要求人们不要对你投反对票;实际上,您更有可能因为他们而收到反对票... Mod here - 不要回滚编辑,@nicomp。 You don't have an applicable use-case for images 在文本上。要么将其添加为文本,要么将其保留。与此无关,诸如“不要对我投反对票”之类的噪音根本不属于您的帖子,并且通常只会让您更多投反对票,因为心理学或其他原因。我已将帖子锁定一小时 - 解锁后不要回滚。 【参考方案1】:

您可以将try_convertcross apply 一起使用

select StartDate,
    Iif(x.v is null,0,1) ValidDate,
    IsNull(Cast(v as varchar(20)),'Undefined Format')
from tBadDate
cross apply (values(Try_Convert(date,StartDate)))x(v)

【讨论】:

以上是关于为啥当我使用 IIF 时,我的表中的某些行而不是其他行的日期转换失败的主要内容,如果未能解决你的问题,请参考以下文章

为啥 SQL 服务器在我的表中插入 0 值而不是使用函数的正确值

Redshift - 问题在存储在表中的表中显示时差

为啥我的表中的第一节标题没有显示?

删除后返回的表行 - jquery

当我使用“或”条件时,为啥我的查询使用过滤而不是索引条件?

Nz 和 IIF 的替代方案(为空)