Использование нулевой даты Oracle

У меня есть приложение с существующими данными, которые имеют Нуль в столбце даты.

Когда я смотрю на него от sqlplus, я вижу: 00-DECEMB

когда я использую функцию дампа на этом столбце, я Добираюсь: Typ=12 Len=7: 100,100,0,0,1,1,1

Я должен работать с существующими данными .NET (никакие изменения в данных, или структура данных или даже существующие sql операторы)

Как взлом делает я считал это значение или пишу это.

Версия дб варьируется, от 8 до 11.

Справка ценилась бы

7
задан Noam 18 January 2010 в 13:09
поделиться

5 ответов

В конце концов, решения моей проблемы не было.

Я сделал следующее: всякий раз, когда бизнес-логика пыталась ввести нулевую дату, я менял ее на 1/1/0001, и когда я получал 1/1/0001 или исключение из базы данных, я вел себя в бизнес-логике так, как будто я получил нулевую дату.

1
ответ дан 7 December 2019 в 12:20
поделиться

Поздравляю, это хранитель!

Тип = 12 Len = 7: 100,100,0,0,1,1,1

Элементами в этой дампе являются век, год, месяц, день, час, минута, секунда. Итак, у вас есть середина ночи 0-0-0000, что определенно не является действительной датой ...

SQL> create table d (d1 date)
  2  /

Table created.

SQL> insert into d values (to_date('00-00-0000', 'dd-mm-yyyy'))
  2  /
insert into d values (to_date('00-00-0000', 'dd-mm-yyyy'))
                              *
ERROR at line 1:
ORA-01847: day of month must be between 1 and last day of month


SQL>

править

Я использовал отличный трюк Гэри, чтобы вставить нулевую дату в таблицу ....

SQL> select * from d
  2  /

D1
---------
00-DECEMB
19-JAN-10

SQL> 

] Итак, по крайней мере, мы знаем, как это сделали ваши "волшебные" разработчики. Теперь все, что нам нужно сделать, это обойти их сообразительность.

Я думаю, что единственный способ сделать это - и вам, вероятно, это не понравится - это создать уровень API, используя представления ....

SQL> create or replace view v_d as
  2  select case when d1 = trash_date then null else d1 end as d1
  3  from d
  4  /

View created.

SQL> select * from v_d
  2  /

D1
---------

19-JAN-10

SQL>

Не менее тревожным аспектом здесь является то, что вы будете необходимо иметь триггеры INSTEAD IF, которые фактически вставляют нулевые даты в базовую таблицу (опять же, используя функцию Гэри). Кроме того, чтобы сохранить те же имена объектов, вам, вероятно, потребуется создать API в другой схеме.

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

последние новости

Я только что наткнулся на это забавное свидание в своем собственном окружении, которое предлагает альтернативное объяснение этим забавным свиданиям. Я добавил столбец DATE в таблицу, в которой были строки. Я использовал предложение DEFAULT, чтобы установить значение по умолчанию для sysdate. Угадайте, что случилось?

SQL> select * from t69
  2  /

        ID
----------
         1
         2

SQL> alter table t69 add col2 date default sysdate not null
  2  /

Table altered.

SQL> select * from t69
  2  /

        ID COL2
---------- ---------
         1 00-DECEMB
         2 00-DECEMB

SQL>

Для записи: sysdate работает должным образом для новых строк ...

SQL> insert into t69 (id) values (3)
  2  /

1 row created.

SQL> select * from t69
  2  /

        ID COL2
---------- ---------
         1 00-DECEMB
         2 00-DECEMB
         3 28-APR-10

SQL>
1
ответ дан 7 December 2019 в 12:20
поделиться
[11377958-

Как узнал APC, вы не можете это исправить от SQL * PLUS. Я столкнулся с аналогичной проблемой от обновленной стоимости JDBC.

Единственное решение, которое я мог бы придумать, должен был обновить ряд, чтобы установить дату разумной (если все еще неверное) значение - вам нужно ссылаться на строку с помощью первичного ключа (которая не включает в себя под сомнение Или используйте ROWID или выполните обновление во всем, где столбец даты снаружи, кажется, что является действительным диапазоном, используя тот же тип инструмента, который создал плохие данные в первую очередь (то есть не SQL * Plus)

- И попробуйте исправить ошибку, вызванную проблему!)

HTH

c.

0
ответ дан 7 December 2019 в 12:20
поделиться

Не уверены, что вы действительно ожидаете, но вы можете генерировать «Cruddy» Dayes через DBMS_STATS.Convert_RAW_Value.

create or replace function stats_raw_to_date (p_in raw) return date is
  v_date date;
  v_char varchar2(25);
begin
  dbms_stats.CONVERT_RAW_VALUE(p_in, v_date);
  return v_date;
exception
  when others then return null;
end;
/
select x, dump(x) y from (select stats_raw_to_date('64640000010101') x from dual);

Итак, что может помочь, это функция

create or replace function trash_date return date deterministic is
  v_date date;
begin
  dbms_stats.CONVERT_RAW_VALUE('64640000010101', v_date);
  return v_date;
end;
/

, тогда вы можете использовать это в таком запросе

select case when date_col = trash_date then null else date_col
from table...
3
ответ дан 7 December 2019 в 12:20
поделиться

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

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

Если у вас есть нулевые (отсутствие или неверные) данные, напишите нулевые данные в таблицу.

0
ответ дан 7 December 2019 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: