如何处理 SAP HANA 中日期转换的异常?

How does one handle exceptions in date casting in SAP's HANA?

问题摘要:

HANA SQL 或 HANA Studio 在视图(计算、属性或分析)中尝试转换为日期以便用户过滤数据时处理无效数据的正确方法是什么?

在 SAP 的 table KONM 中,字段 KSTBM 是 decimal(15,3) 的数据类型。这个字段对错,以YYYYMMDDHHM.MSS格式存储一个日期值。 (我是用户而不是系统的设计者。为什么有人将日期存储在小数字段而不是哦 date/time 字段中超出了这个问题的范围。)

所以有效值如:

存在并且可以使用 to_timestampdaydate 或类似函数轻松转换。

不幸的是,在此 table 中输入了一些错误条目,导致数据无法转换为日期时间,例如:

在此类无效记录上使用 to_Timestampdaydate 函数时,会出现以下错误:

SAP DBTech JDBC: [2048]: column store error: search table error: [6860] invalid date, time or timestamp value;

[303]: invalid DATE, TIME or TIMESTAMP value:

我同意这些日期无效...因此我知道为什么会抛出错误。

虽然我很想解决根本原因,然后更正错误数据;这不是目前的选择。不同的团队,不同的资源不同的优先级。所以这是他们要做的事情的清单,但我有需要 WEBI 报告的用户;由于存在不良数据...我仍然必须处理它。

我想做的是在 HANA Studio 中创建一个 Calculated_view,它可以成功处理这些错误的日期。但是我一直无法找到 try catch 或其他类型的异常处理,这些异常处理基本上可以让我将这些日期设置为 NULL,这样用户仍然可以获得其他相关数据,并且能够看到他们在可以纠正的系统。

自从抛出此错误以来,当 WEBI 报告为 运行 时,无法从 Universe 返回任何记录。我发现了一些选项,涉及在所有可能的时间创建 date/time table....(我希望你能明白为什么我不想这样做)或创建一个函数(但它缺乏具体的方向;毕竟我是 HANA、Universe 和 WEBI 的新用户,这就是问题存在的原因)

这是 HANA Studio 中可能 运行 的示例:

  WITH MyExample as (SELECT 201701011.230 as KSTBM, 0 isBad from dummy union all
                     SELECT 201702301.000 as KSTBM, 1 isBad from dummy union all
                     SELECT 201702171.230 as KSTBM, 0 isBad from dummy union all
                     SELECT 201702192.400 as KSTBM, 1 isBad from dummy)

  SELECT to_timestamp(To_DECIMAL(KSTBM*100000,15,0)) TS, 
         isBad
  FROM MyExample A
  WHERE isBad = 1

将 isBad 更改为 0 并且有效;将 isBad 更改为 1,您会看到错误。

问题方面:

  1. 无论 isBad 是 1 还是 0,我如何才能将此查询无误地发送到 运行?
  2. 是否有 method/manner 到 include/not 包含错误数据(也许在结果中将所有错误数据设置为 NULL,然后空数据可以 included/excluded 作为用户的选项?
  3. 是否有一种方法可以在视图中识别计算列中的这些错误记录,这样我们就不会在无效时尝试转换它们,而在有效时进行尝试?
  4. 我的方法是否完全错误,我需要重新训练我的 Oracle/MS SQL/MySQL 大脑以不同的方式思考?其他语言我会处理异常,或者尝试捕获或使用 isdate() 在尝试转换之前检查是否有效...我只是在这里看不到这些选项(但我是新手,也许根本无法使用帮助很好)

感谢您阅读我冗长的问题。希望我提供了足够的细节。

我正在努力避免:

您可能需要为此使用 tstmp_is_valid() 函数:

WITH MyExample as (SELECT 201701011.230 as KSTBM, 0 isBad from dummy union all
                     SELECT 201702301.000 as KSTBM, 1 isBad from dummy union all
                     SELECT 201702171.230 as KSTBM, 0 isBad from dummy union all
                     SELECT 201702192.400 as KSTBM, 1 isBad from dummy)

  SELECT KSTBM,
         tstmp_is_valid(KSTBM*100000), 
         isBad
  FROM MyExample A;

KSTBM           TSTMP_IS_VALID(KSTBM*100000)    ISBAD
201,701,011.23  1                               0    
201,702,301     0                               1    
201,702,171.23  1                               0    
201,702,192.4   0                               1    

请参阅 CDS documentation

还有一个函数:DATS_IS_VALID("STRINGDATE") 将评估日期和 return 1 或 0。如果日期是有效日期,则为 1。

WITH CTE AS 
(SELECT '00000000' as STRINGDATE from dummy union all
SELECT '20190101'  from dummy union all
SELECT '20190230' from dummy union all
SELECT '20191301' from dummy union all
SELECT '20191232' from dummy union all
SELECT '20190228' from dummy union all
SELECT '20200228' from dummy union all
SELECT '20200229' from dummy )

SELECT StringDate, DATS_IS_VALID("STRINGDATE") isValid, case when DATS_IS_VALID("STRINGDATE") =1 then 
cast("STRINGDATE" as date) else cast(null as date) end RightDataType from CTE;

在上面的示例中,我们只是将日期转换为有效日期,并在结果中无效时将其设置为空。如果您有正在保存但无效的字符串日期,则很有用。