Oracle регулярное выражение для проверки времени - PullRequest
0 голосов
/ 18 марта 2020

Я пытаюсь проверить регулярное выражение в oracle SQL, чтобы проверить формат времени:

Требуемый формат, который я хочу проверить:

2/27/2020 3:53:02 PM

У меня уже есть создал регулярное выражение для формата даты, такого как:

20200227 --> using REGEXP_LIKE('20190222', '^\d{4}(0[1-9]|(1[0-2]))(0[1-9]|[1-2][0-9]|3[0-1])$')

Может ли кто-нибудь дать мне подсказку о формате времени?

Ответы [ 3 ]

3 голосов
/ 18 марта 2020

Для меня это выглядит так, как будто вы запустили его неправильно . Если вы хотите проверить формат date ( time ), вы сохраняете его как строку, что является большой ошибкой.

Если вы установите этот столбец ( или что бы то ни было) как DATE, который - в Oracle - содержит и дату, и время, тогда база данных позаботится о том, чтобы вы могли вводить только допустимые значения.

Формат, который вы упомянули, или любой другой, имеет значение отображение , а не хранение .


Один из вариантов - принудительное преобразование TO_DATE; как-то так:

SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';

Session altered.

SQL> set ver off
SQL> select to_date('&date_value', 'mm/dd/yyyy hh:mi:ss am') result from dual;
Enter value for date_value: 2/27/2020 3:53:02 pm

RESULT
-------------------
27.02.2020 15:53:02

SQL> /
Enter value for date_value: 13/54/2020 x:23:83 am
select to_date('13/54/2020 x:23:83 am', 'mm/dd/yyyy hh:mi:ss am') result from dual
               *
ERROR at line 1:
ORA-01843: not a valid month


SQL>

Итак: если конвертация работает, то формат в порядке. В противном случае вы ввели что-то глупо , и преобразование не пройдет. Такой код можно использовать как функцию, которая возвращает, например, логическое значение.

1 голос
/ 18 марта 2020

Не используйте регулярное выражение, так как крайние значения сделают выражение длинным и сложным (т. Е. Месяцы могут иметь 28-31 день, високосные годы каждые 4 года ... за исключением кратных 100 ... кроме кратных из 400).

Например, регулярное выражение даты ^\d{4}(0[1-9]|(1[0-2]))(0[1-9]|[1-2][0-9]|3[0-1])$ будет проверять 20190229 или 20200230 или 20200931, ни одна из которых не является действительной датой.

Регулярное выражение времени это проще, так как у вас есть только часы 0-23, минуты 0-59, секунды 0-59 (при условии, что вы игнорируете високосные секунды) и, возможно, дробные секунды и будут:

([01]\d|2[0-3]):[0-5]\d:[0-5]\d(\.\d+)?

Однако, более простой способ это просто попытка выполнить преобразование в DATE, и если он потерпит неудачу, вы знаете, что он недействителен. Если вы используете Oracle 12.2 или более позднюю версию, вы можете использовать встроенную функцию VALIDATE_CONVERSION :

SELECT validate_conversion( '20200230000000' AS DATE, 'YYYYMMDDHH24MISS' )
FROM   DUAL

Если вы используете более раннюю версию, вы можете создать пользовательская функция, чтобы попытаться выполнить преобразование, и если возникает исключение, то вы знаете, что ввод неверен:

CREATE FUNCTION isValidDate(
  date_string  IN VARCHAR2,
  format_model IN VARCHAR2 DEFAULT 'FXYYYYMMDDHH24MISS'
) RETURN NUMBER
IS
  d DATE;
BEGIN
  d := TO_DATE( date_string, format_model );
  RETURN 1;
EXCEPTION
  WHEN OTHERS THEN
    RETURN 0;
END;
/
0 голосов
/ 18 марта 2020

Просматривая строку Regex, я обнаружил, что этот выполняет ту работу, которую я ищу:

REGEXP_LIKE('2/27/2020 3:53:02 PM','^\d{1,2}\/\d{1,2}\/\d{4} \d{1,2}:\d{1,2}:\d{1,2} [AP]M\z')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...