【问题标题】:Convert VARCHAR in format YYMMDD to YYYYMMDD and ignore invalid date formats将 YYMMDD 格式的 VARCHAR 转换为 YYYYMMDD 并忽略无效的日期格式
【发布时间】:2017-07-20 10:00:35
【问题描述】:

我有一个表,其中包含一个名为 ArrivalDate 的 VARCHAR 字段,格式为 yymmdd(例如 170202)。 我正在编写一个将其转换为 yyyymmdd 的查询,因此它应该变为 20170202。

但是我的问题是我需要处理在字段中输入不适当数据的情况,并且我的查询需要排除该数据。我通过使用 TSQL 的 ISDATE 函数来实现此排除。我还需要选择最近的条目(为此我使用按 asc 排序)。

我正在使用各种转换来编写此查询,下面是我的示例表和数据的实现。

Declare @tmp TABLE (theDates VARCHAR(MAX))

INSERT INTO @tmp VALUES('170202')

SELECT TOP 1 t.theDates
WHEN (ISDATE(t.theDates) = 1) THEN CONVERT( VARCHAR(max),CONVERT(datetime t.theDates), 112)
FROM @tmp t
WHERE (ISDATE(t.theDates) = 1)
ORDER BY CAST(t.theDates as DATE)

但是,我不喜欢我的方法,它偶尔会导致转换失败,并引发错误,例如 02/02/02 等值会中断查询。有人可以告诉我编写此功能的更好方法吗?

非常感谢!

【问题讨论】:

  • 为什么你会存储日期而不是日期?
  • 使用 SQL Server 2012 及更高版本,TRY_CONVERT 可能就是您要找的。​​span>
  • 这只是与@ErikPhilips 合作的表格。我没有编写架构,我永远不会将日期存储为 VARCHAR

标签: sql-server tsql date stored-procedures


【解决方案1】:

您可以使用TRY_CONVERTCONVERT 来获取正确的格式并转换值。然后检查字符串是否正好是 6 个字符,以防止返回其他格式。

SELECT
  convert(char(10),convert(date, theDates, 12),112)
FROM
  (values('02/02/02'),('170202')) x(theDates)
WHERE
  try_convert(date, theDates, 12) is not null
  and len(theDates) = 6

【讨论】:

  • 您的解决方案效果最好。非常感谢。也谢谢大家
【解决方案2】:

你可以使用cast(@date as datetime)

declare @date varchar(max);
    set @date='170202';
    select
    CASE WHEN (ISDATE(cast(@date as datetime)) = 1) 
        THEN CONVERT(VARCHAR(max), CONVERT(datetime,  cast(@date as datetime)), 112) end
        from table

    set @date='02/02/02';
    select
    CASE WHEN (ISDATE(cast(@date as datetime)) = 1) 
        THEN CONVERT(VARCHAR(max), CONVERT(datetime,  cast(@date as datetime)), 112) end
        from table

【讨论】:

  • 感谢您的回答。但是,如果我在表中插入相同的值,一个具有冲突格式,一个没有(02/12/02 和 021202 到表中并运行您的查询,结果会有所不同
  • 021202 输出为 20021202 02/12/02 输出为 20020212 看起来 mm 和 dd 已根据斜线是否在日期中交换。任何想法如何解决这个问题?
  • @Mark 其他一些答案处理
  • @t-clausen.dk 谢谢你的回答,我投票给它最佳答案
【解决方案3】:

请使用 create 函数检查 dateformat 是否有效,并在您的查询中使用此功能。

ALTER  FUNCTION dbo.f_CheckDate
(@InDate nvarchar(25))
RETURNS DATE
AS
    BEGIN
        declare @Return DATETIME
        select @return = CASE WHEN ISDATE(@InDate) = 1
                             THEN   @InDate
                            ELSE NULL
                            END
        return @return
    END

【讨论】:

    【解决方案4】:

    您可以使用TRY_CASTTRY_CONVERT,如果无法转换值,它将返回NULL。

    SELECT 
      TRY_CAST('20170228' AS DATETIME),
      TRY_CAST('170228' AS DATETIME),
      TRY_CONVERT(DATETIME, '20170228'),
      TRY_CONVERT(DATETIME, '170228')
    

    这适用于 SQL Server 2012 及更高版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 2020-07-01
      • 2014-07-03
      • 1970-01-01
      • 2013-08-13
      相关资源
      最近更新 更多