Как предотвратить «плохие» даты в Oracle? - PullRequest
0 голосов
/ 24 июня 2019

Я работаю над базой данных для нашего проекта.Наши сотрудники смогли вставить дату '00 .00.0000 'в Oracle из Java (тип данных столбца - DATE).Я предполагаю, что это связано с необработанными значениями, как в этом примере:

alter session set nls_date_format='fmdd.month.yyyy hh24:mi:ss';
declare
  d date;
begin
  dbms_stats.convert_raw_value(hextoraw('7764057f7f77aa'), d);
  dbms_output.put_line(d);
end;
/

127.may.1900 126:118:87

Как я могу предотвратить это?

1 Ответ

1 голос
/ 24 июня 2019

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

Однако , вам не нужно делать это, так как вы должны предписывать, чтобы произвольный код не выполнялся в ваших системах, и весь код приложения должен включать проверку входных данных, чтобы в базу данных вставлялись только очищенные значения.

Пример:

Установка Oracle :

CREATE TABLE Dates (
  d DATE
);

CREATE FUNCTION isValidDate( dt IN DATE ) RETURN NUMBER
IS
  d DATE;
BEGIN
  d := TO_DATE( TO_CHAR( dt, 'fxYYYY-MM-DD HH24:MI:SS' ), 'fxYYYY-MM-DD HH24:MI:SS' );
  RETURN 1;
EXCEPTION
  WHEN OTHERS THEN
    RETURN 0;
END;

Вставить даты :

declare
  d DATE;

  FUNCTION createUnvalidatedDate(
    centuries INT := 0,
    years     INT := 0,
    months    INT := 0,
    days      INT := 0,
    hours     INT := 0,
    minutes   INT := 0,
    seconds   INT := 0
  ) RETURN DATE
  IS
    dt         DATE;
    hex_string CHAR(14);
  BEGIN
    hex_string := LPAD( TO_CHAR( centuries + 100, 'fmXX' ), 2, '0' )
               || LPAD( TO_CHAR( years + 100,     'fmXX' ), 2, '0' )
               || LPAD( TO_CHAR( months,          'fmXX' ), 2, '0' )
               || LPAD( TO_CHAR( days,            'fmXX' ), 2, '0' )
               || LPAD( TO_CHAR( hours + 1,       'fmXX' ), 2, '0' )
               || LPAD( TO_CHAR( minutes + 1,     'fmXX' ), 2, '0' )
               || LPAD( TO_CHAR( seconds + 1,     'fmXX' ), 2, '0' );
    dbms_stats.convert_raw_value(hextoraw(hex_string), dt);
    RETURN dt;
  END;
begin
  d := createUnvalidatedDate( 19, 0, 5, 127, 126, 118, 87 );
  INSERT INTO Dates ( d ) VALUES ( d );
  d := createUnvalidatedDate( 0, 0, 0, 0, 0, 0, 0 );
  INSERT INTO Dates ( d ) VALUES ( d );
  d := createUnvalidatedDate( 20, 19, 6, 24, 10, 28, 30 );
  INSERT INTO Dates ( d ) VALUES ( d );
end;
/

Check Validity :

SELECT d, isValidDate( d ) AS valid
FROM   Dates;

Выходы:

D                     | VALID
:-------------------- | ----:
1900-5-127T126:118:87 |     0
0-0-0T0:0:0           |     0
2019-6-24T10:28:30    |     1

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

дБ <> скрипка здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...