【问题标题】:Issue in using TRY_PARSE in CASE WHEN Statement在 CASE WHEN 语句中使用 TRY_PARSE 的问题
【发布时间】:2018-03-19 11:58:25
【问题描述】:

我需要使用不同的格式验证日期,例如 Thursday March 15, 2018, 05-21-1995, 04.03.1934 并且我可能会得到像 N/A, #### etc., 这样的无效日期。我正在使用以下查询来验证存储过程中的日期,这里我将日期插入日期列并设置错误标志如果有一个无效日期。

INSERT INTO table_name(date_column,date_error) 
    SELECT 
        CASE WHEN TRY_PARSE(date_column AS datetime USING 'en-US') is NULL THEN date_column
            ELSE TRY_PARSE(date_column AS datetime USING 'en-US')
            END as date_column,
        CASE WHEN TRY_PARSE(date_column AS datetime USING 'en-US') is NULL THEN 1
            ELSE 0
            END as date_error
        FROM @temp_table;

对于日期值####,我收到错误为Conversion failed when converting date and/or time from character string

【问题讨论】:

  • 您希望case 表达式返回什么?一个分支是字符串,另一个分支是日期/时间。 SQL Server 决定您需要日期/时间,但您会收到转换错误。
  • 如果是有效日期,我想格式化日期并插入表格,如果日期无效,我想按原样插入并设置错误标志。
  • 这意味着您想将您的datetime 存储为varchar...这是一个坏主意(有很多原因)。
  • @Mdumanoj 为什么不能对无效日期使用 NULL?
  • 扩展@GordonLinoff 的评论:CASE 语句不能为不同的行返回不同的数据类型,并且您的目标表不能在不同的行中存储不同的数据类型。这对我来说意味着您可能需要一个新的表结构; INSERT INTO table_name (date_value, original_string_value) SELECT TRY_PARSE(date_column AS datetime USING 'en-US'), date_column FROM @temp_table。这将为每一行提供原始字符串,如果转换成功,则为日期时间值,如果转换失败,则为 NULL。但是尝试将字符串和日期时间都存储在一列中是错误的

标签: sql sql-server stored-procedures tryparse


【解决方案1】:

你不能将两种不同的类型放在一列中

这可能对你有用

declare @T table (pk int identity primary key, varDt varchar(100));
insert into @T (varDt) values ('Thursday March 15, 2018'), ('05-21-1995'), ('N/A'), ('####'), ('easter'), ('');
declare @Tf table (pk int primary key, varDt varchar(100), needFix bit, dt datetime);
insert into @Tf
select t.pk, t.varDt 
     , case when TRY_PARSE(t.varDt AS datetime USING 'en-US') is null then 1 else 0 end as needFix
     , TRY_PARSE(t.varDt AS datetime USING 'en-US') as dt     
from @T t;
select * 
from @Tf tf 
order by needFix desc, pk;

【讨论】:

    【解决方案2】:

    感谢您的所有 cmets。正如@gordon-linoff 所说,我们在 CASE WHEN 语句中不能有两种不同的数据类型。所以,我将 else 语句转换为 varchar。

    INSERT INTO table_name(date_column,date_error) 
    SELECT 
        CASE WHEN TRY_PARSE(date_column AS datetime USING 'en-US') is NULL THEN date_column
            ELSE CAST(TRY_PARSE(date_column AS datetime USING 'en-US') AS varchar(max))
            END as date_column,
        CASE WHEN TRY_PARSE(date_column AS datetime USING 'en-US') is NULL THEN 1
            ELSE 0
            END as date_error
        FROM @temp_table;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-17
      相关资源
      最近更新 更多