2012-01-04 2 views
10

Oracle 10.2.0.5Как определить недействительные (испорченные) значения, сохраненные в DATE столбцах Oracle

Что это самый простой способ для идентификации строк в таблице, которые имеют «неправильные» значения в столбцах DATE. Под «недействительным» здесь я имею в виду двоичное представление, которое нарушает правила Oracle для значений даты.

У меня недавно возникла проблема с недопустимой датой, хранящейся в столбце.

Я был в состоянии использовать предикат запроса для поиска конкретной проблемной строки:

WHERE TO_CHAR(date_expr,'YYYYMMDDHH24MISS') = '00000000000000' 

В случае, если я был, байты века были недействительны ...

select dump(h.bid_close_date) from mytable h where h.id = 54321 

Typ=12 Len=7: 220,111,11,2,1,1,1 

Столетия байты должен быть 100 + двухзначный век. В этом случае было добавлено дополнительно 100, как будто значение столетия было «120», что сделало год «12011». (Единственный способ, которым я знаю, чтобы получить недопустимые значения DATE в базе данных, использует OCI, используя собственное 7-байтовое представление DATE.)

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

Мой вопрос: существует ли более общий или более простой подход (предпочтительно с использованием оператора SQL SELECT) для идентификации строк с «недопустимыми» значениями в столбцах DATE.

+0

Вы можете выбрать все даты не в пределах допустимого диапазона? – ProfessionalAmateur

+1

Там была * ошибка в более ранних версиях Oracle (9.x?), Которая позволяла делиться на нуль значений INTERVAL, чтобы их можно было обнаружить и получить недопустимые значения. –

+0

Как вам удалось попасть в базу данных в первую очередь? –

ответ

3

Без добавления функции, простой предикат

TO_CHAR(date_col,'YYYYMMDDHH24MISS') = '000000000000' 

является удовлетворительным для выявления поврежденных значений, хранящихся в столбце DATE Oracle. Добавление функции оказывается ненужным. Проверка на поврежденные даты должна быть выполнена в инструкции SQL SELECT и не требует, чтобы у пользователя была привилегия CREATE FUNCTION в базе данных.

4

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

Что-то вроде этого:

create or replace function is_a_date 
    (p_date in date) 
    return varchar2 
is 
    d date; 
begin 
    d := to_date(to_char(p_date, 'SYYYYMMDDHH24MISS'), 'SYYYYMMDDHH24MISS') ; 
    if d != p_date then 
     return 'not a proper date'; 
    else 
     return 'good date'; 
    end if; 
exception 
    when others then 
     return 'not a date'; 
end; 
/

Это преобразует дату в строку и обратно. Он ловит исключения, брошенные датой. Если конечный продукт не совпадает с датой ввода, то, по-видимому, что-то заблудилось в переводе; честно говоря, я не уверен, что дата 12011 будет успешно перенесена в строку, так что это подход с поясом. Это немного сложно написать эту утилиту без каких-либо тестовых данных!

Этот запрос будет идентифицировать все недействительные даты:

select h.id, dump(h.bid_close_date) 
from mytable h 
where h.bid_close_date is not null 
and is_a_date(h.bid_close_date) != 'good date'; 
+0

+1 Предположим, что это действительно работает (у меня также нет тестовых данных). Мне это нравится намного лучше, чем моя идея разбора строки, возвращаемой по 'свалке'. –

+1

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

+0

@ShannonSeverance - в этом случае я думаю, что наиболее разумным вариантом является фильтрация запроса, поэтому мы будем беспокоиться только о строках, в которых заполняется столбец даты. – APC

0

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

Однако спросите себя, действительно ли у вас есть дата 1066-10-14? Это юридическая ценность, но вы, вероятно, не имеете счетов, напечатанных в этот день, например. Таким образом, вы можете опрокинуть неверную проверку даты в более крупную проблему того, что вы считаете действительным в контексте своего приложения.

+0

Это не отвечает на вопрос, который я задал, и это был лучший способ идентифицировать существующее повреждение в столбце DATE базы данных Oracle. – spencer7593

+0

Действительно, нет - это советы о том, как выбрать методологию, а также о более широких соображениях достоверности данных. –

0

Это определяет недействительные месяцев

SELECT rowid, 
     pk_column, 
     DUMP(date_column, 1010) AS dump1 
FROM table 
WHERE TO_NUMBER(SUBSTR(DUMP(date_column, 1010), INSTR(DUMP(date_column, 1010), 
               ',', 1, 2 
                ) + 1, 
            INSTR(DUMP(date_column, 1010), ',', 1, 3) - (
            INSTR(DUMP(date_column, 1010), ',', 1, 2) + 1 
           ))) = 0; 

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

Смежные вопросы