Как обрабатывать исключения при приведении даты в SAP HANA?

РЕЗЮМЕ ВОПРОСА:

Как правильно в HANA SQL или HANA Studio в представлении (вычислении, атрибуте или аналитике) обрабатывать недопустимые данные при попытке привести к дате, чтобы пользователь мог фильтровать данные?

В таблице SAP KONM поле KSTBM представляет собой десятичный тип данных (15,3 ). Это поле правильно или неправильно, хранит значение даты в формате ГГГГММДДЧЧМ.MSS. (Я пользователь, а не разработчик системы. Почему кто-то хранит дату в десятичном поле вместо поля даты / времени, выходит за рамки этого вопроса.)

Так что допустимые значения, такие как:

  • 201703290 (да, 2017 действительный год 03 действительный месяц и 29 действительный день в этом месяце для этого года.)
  • 201703301.130 (да, 2017 действительный год 03 действительный месяц и 30 действительный день в этом месяце для этого года, а 11:30 - действительное время)

существуют и могут быть легко преобразованы с помощью to_timestamp, daydate или аналогичной функции.

К сожалению, в эту таблицу было внесено несколько неправильных записей, в результате чего данные не могут быть преобразованы в дату и время, например:

  • 201702290 (Недействительный день февраля в 2017 году не было 29 дней)
  • 201713500 (недействительный месяц 12 месяцев, а не 13)
  • 201712312.400 (Неверный час 00: 00: 00-23: 59: 59 нет 24)
  • 201712310.060 (Неверная минута 00:60 будет 01:00)
  • 201712310.090 (Неверная минута 00:90 будет 01:30)

При использовании функций to_Timestamp или daydate для таких недопустимых записей возникает следующая ошибка:

SAP DBTech JDBC: [2048]: ошибка хранилища столбцов: ошибка таблицы поиска: [6860] недопустимое значение даты, времени или отметки времени;

or

[303]: недопустимое значение DATE, TIME или TIMESTAMP:

Я согласен, что это недопустимые даты ... и поэтому я знаю, почему возникает ошибка.

Хотя я хотел бы исправить основную причину, а затем исправить неверные данные; в настоящее время это не вариант. Разные команды, разные ресурсы, разные приоритеты. Так что это в их списке дел, но у меня есть пользователи, которым нужны отчеты WEBI; и поскольку существуют плохие данные ... мне все еще нужно с этим справиться.

Я пытаюсь создать Calculated_view в HANA Studio, который может успешно обрабатывать эти ошибочные даты. Но мне не удалось найти try catch или другой тип обработки исключений, который позволил бы мне в основном установить эти даты на NULL, чтобы пользователь по-прежнему получал другие соответствующие данные и мог видеть, что у них есть некоторые плохие данные в система, которую можно исправить.

В его нынешнем виде с момента возникновения этой ошибки никакие записи не могут быть возвращены из юниверса при запуске отчета WEBI. Я нашел несколько вариантов, которые включают создание таблицы даты / времени со всеми возможными временами .... (надеюсь, вы понимаете, почему я не хочу этого делать) или создание функции (но в ней отсутствуют конкретные указания; В конце концов, я новый пользователь HANA, Universes и 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. Есть ли способ / способ включить / не включать плохие данные (возможно, установить для всех плохих данных значение NULL в результате, а затем пустые данные могут быть включены / исключены по выбору пользователя?
  3. есть ли способ в представлении идентифицировать эти плохие записи в вычисляемом столбце, чтобы мы не пытались преобразовать их, если они недействительны, и пытались, когда они действительны?
  4. Мой подход просто неправильный, и мне нужно переучить свой мозг Oracle / MS SQL / MySQL, чтобы думать по-другому? На других языках я бы обработал исключения или попробовал поймать или использовать isdate() для проверки допустимости перед попыткой приведения ... Я просто не вижу здесь этих параметров (но я новичок и, возможно, просто не могу очень хорошо использовать справку пока что)

Спасибо, что прочитали мой длинный вопрос. Надеюсь, я предоставил достаточно подробностей.

Я пытаюсь избежать:


person xQbert    schedule 05.04.2018    source источник
comment
Проголосуйте за действительно хорошо подготовленный вопрос, включая пример исполняемого файла. Молодец!   -  person Lars Br.    schedule 06.04.2018
comment
Дополнение: хотя мы можем сделать это в запросах hana, я не рекомендую с точки зрения производительности, если эти поля будут использоваться в качестве фильтров в запросах. Производительность при приведении к настоящему времени ужасна для больших наборов данных; Лучше, если ваши пользователи будут искать по строковым или десятичным числам. (вздох) Я считаю, что это связано с отсутствием индекса для результата, основанного на функции.   -  person xQbert    schedule 30.06.2020
comment
Вы можете создать своего рода индекс на основе функций, создав вычисляемый столбец. Однако даже в руководстве по производительности упоминается, что обычно лучше преобразовать сравниваемое буквальное значение в правильный тип / формат данных вместо сравниваемого столбца.   -  person Lars Br.    schedule 01.07.2020
comment
Может, тогда что-то не так делали. Если вы говорите преобразовать дату строки в дату в представлении «Расчет»; и позволить пользователю передать тип данных даты для фильтрации ... Мы сделали это, используя вычисляемые столбцы в Hana. Затем мы устанавливаем фильтр для этого вычисляемого столбца из вселенной BO, связанного с представлением вычислений; производительность была ужасной. Когда мы использовали строковую дату в юниверсе вместо вычисляемого столбца, производительность улучшилась в 10 раз. возможно, это связано с тем, что возвращаемые наборы результатов часто содержат более 100 000 записей для данной иерархии продуктов верхнего уровня.   -  person xQbert    schedule 01.07.2020


Ответы (1)


Вы можете использовать для этого функцию 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.

Также есть функция: DATS_IS_VALID("STRINGDATE"), которая оценит дату и вернет 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;

В приведенном выше примере мы просто преобразуем дату в действительную дату и устанавливаем ее значение null, если она недопустима в результатах. Полезно, если у вас есть строковые даты, которые сохраняются, но недействительны.

person Lars Br.    schedule 06.04.2018
comment
Идеально! Я искал функцию, которая была бы чем-то вроде isDate () в SQL-сервере! Эта документация может быть источником, который я ищу. Спасибо! Могу ли я считать, что функции ABAP можно вызывать из студии Hana (это работает, я так думаю)? Знаете ли вы, выполняет ли этот подход переключение контекста, которое снижает производительность запроса, как это делает Oracle при переключении с SQL на PL / SQL? - person xQbert; 06.04.2018
comment
Под переключением контекста я подразумеваю переключение с одного движка на другой, который, как известно, снижает производительность. Конечно, это работает, и моя философия - делать что-то, смеяться, делать это правильно, а затем улучшать. Я сейчас нахожусь на фазе «делать что-то и смеяться». но просят сделать это правильно и улучшить в рамках подготовки к росту. - person xQbert; 06.04.2018
comment
Это много вопросов ... быстрые ответы: нет, вы не можете взять любую функцию ABAP и запустить ее в HANA (я упомянул, что это специфическая для HANA реализация функции CDS, независимой от БД). Эта функция обрабатывается так же, как и любая другая встроенная функция SQL, и никакого дополнительного переключения контекста не требуется - это не функция SQLScript, а встроенная. Надеюсь, это поможет. - person Lars Br.; 07.04.2018