2

QUESTION SUMMARY:

What is the proper way within HANA SQL or HANA Studio in a view (Calculation, attribute or Analytic) to handle invalid data when attempting to cast to a date so a user can filter the data?

In SAP's table KONM the field KSTBM is a datatype of decimal(15,3). This field right or wrong, stores a date value in YYYYMMDDHHM.MSS format. (I'm a user not a designer of the system. Why anyone stores a date in a decimal field instead of a oh a date/time field is beyond the purview of this question.)

So valid values such as:

  • 201703290 (yep 2017 valid year 03 a valid month and 29 a valid day in that month for that year.)
  • 201703301.130 (yep 2017 valid year 03 a valid month and 30 a valid day in that month for that year along with 11:30 being a valid time)

exist and can easily be cast using a to_timestamp or daydate or similar function.

Unfortunately a few bad entries have been made into this table resulting in data that is unable to be cast to a date time such as:

  • 201702290 (Invalid day Feb didn't have 29 days in 2017)
  • 201713500 (Invalid Month 12 months not 13)
  • 201712312.400 (Invalid hour 00:00:00-23:59:59 there is no 24)
  • 201712310.060 (Invalid Minute 00:60 would be 01:00)
  • 201712310.090 (Invalid Minute 00:90 would be 01:30)

When using to_Timestamp or daydate functions on such invalid records the following error is presented:

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

or

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

I agree those are invalid dates... and thus I know why the error is thrown.

While I would love to fix the root cause and then correct the bad data; that isn't presently an option. Different teams, different resources different priorities. So it's on their list of things to do but I have users who need the WEBI reports; and since the bad data exists... I still have to handle it.

What I'm trying to do is create a Calculated_view in HANA Studio which can handle these erroneous dates successfully. But I've not been able to find a try catch or other type of exception handling which would allow me to basically set these dates to NULL so the user still gets the other relevant data and are able to see they have some bad data in the system that the could correct.

As it stands since this error is thrown, no records are able to be returned from the universe when the WEBI report is run. I've found a few options that involve creating a date/time table with all possible times.... (I hope you can see why I don't want to do that) or creating a function (but it lacks specific directions; I'm afterall a new user to HANA and Universes and WEBI which is why the question exists)

Here's an example that could be run in 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

Change isBad to 0 and it works; change isBad to 1 and you see the error.

Question Aspects:

  1. How can I get this query to run without error regardless of isBad being 1 or 0?
  2. Is there a method/manner to include/not include the bad data (perhaps set all bad data to NULL in the result and null data can then be included/excluded as a user's option?
  3. is there a way in a view to identify these bad records in a calculated column so we don't try and convert them if invalid and do try when valid?
  4. Is my approach simply wrong and I need to retrain my Oracle/MS SQL/MySQL brain to think differently? Other languages I'd handle exceptions, or try catch or use isdate() to check for valid before attempting to cast... I just don't see those options here (but I'm new and perhaps simply unable to use the help very well yet)

Thanks for reading my long drawn out question. Hopefully I've provided sufficient details.

I'm trying to avoid:

4

1 回答 1

3

You might want to use the tstmp_is_valid() function for this:

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    

See the CDS documentation on that.

There's also a function: DATS_IS_VALID("STRINGDATE") which will evaluate a date and return a 1 or 0. 1 being if date is a valid date.

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;

In the above example we simply convert a date to a valid date and set it to null when not valid in the results. Useful if you have string dates that are getting saved but not valid.

于 2018-04-06T02:43:58.173 回答