Причины получения (ORA-8102 «индексный ключ не найден»)

Итак, у меня есть таблица с индексом с именем IDX_ATS_CALC_END_TIME. Столбец представляет собой значение метки времени. Этот столбец также имеет триггер который автоматически заполняет столбец, когда другой столбец (Interval_duration) заполняется или обновляется.

Ниже приведен триггер:

TRIGGER "DATAMART"."TRG_ATS_CALC_END_TIME" 
    BEFORE INSERT OR UPDATE OF INTERVAL_DURATION ON DATAMART.AGG_TIME_SUMMARY
    FOR EACH ROW
    DECLARE
BEGIN
IF :New.INTERVAL_DURATION > 0 THEN
   :New.calc_end_time := :New.start_date_time  + pb_util.secondtointerval(:New.INTERVAL_DURATION);
ELSE
:NEW.CALC_END_TIME := :New.start_date_time;
END IF;

    EXCEPTION
    WHEN OTHERS THEN
      pb_util.logdata(1, 'TRG_ATS_CALC_END_TIME', 'Exception Thrown in interval:  ' || :New.Interval_DURATION, SQLERRM  || ' stack: ' || dbms_utility.format_error_backtrace);

END TRG_ATS_CALC_END_TIME;

Когда моя таблица изначально заполняется, проблем нет. Моя проблема в том, что когда я иду выполнять вставку/ обновить таблицу и попытаться изменить этот столбец, либо напрямую изменив столбец, либо просто обновив столбец interval_duration. umn у меня есть эта ошибка:

ORA-08102: ключ индекса не найден, obj # 97523, файл 4, блок 244 (2)

Упомянутый индекс является функционирующим индексом. В индексе используется функция sys_extract_utc в столбце calc_end_time.

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

ANALYZE INDEX IDX_ATS_CALC_END_TIME VALIDATE STRUCTURE;

и он вернулся без проблем.

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

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

ОБНОВЛЕНИЕ: ниже вы найдете код функции pb_util.secondtointerval():

FUNCTION SecondToInterval
  (Seconds_IN NUMBER
  )
RETURN CONST.PBInterval
IS
  sec            NUMBER(20, 9);
  days           NUMBER;
  hours          NUMBER;
  minutes        NUMBER;
  seconds        NUMBER(20, 9);
  IntervalAsText NVARCHAR2(32);
  ReturnInterval INTERVAL DAY(9) TO SECOND(9);
begin
  sec     := NVL(Seconds_IN, 0);

  days    := trunc(sec/(24*60*60));
  sec     := sec - days*24*60*60;

  hours   := trunc(sec/(60*60));
  sec     := sec - hours*60*60;

  minutes := trunc(sec/60);
  sec     := sec - minutes*60;

  seconds := trunc(sec);

  sec     := sec - seconds;
  sec     := trunc(1000000000*sec);

  IntervalAsText := cast(days as nvarchar2)
    || ' ' || cast(hours as nvarchar2)
    || ':' || substr('00' || cast(minutes as nvarchar2), -2, 2)
    || ':' || substr('00' || cast(seconds as nvarchar2), -2, 2)
    || '.' || substr('000000000' || cast(sec as nvarchar2), -9, 9);

  --dbms_output.put_line(intervalastext);

  ReturnInterval := TO_DSInterval(IntervalAsText);
  --ReturnInterval := TO_DSInterval('999999999 23:59:59.999999999');
  --dbms_output.put_line(ReturnInterval);

  RETURN ReturnInterval;
EXCEPTION
    WHEN OTHERS THEN
   pb_util.logdata(1, 'PB_UTIL.SecondToInterval', 'ERROR(99A): ', intervalastext);
                dbms_output.put_line(intervalastext);
                RAISE;

end SecondToInterval;

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

Будем признательны за любую помощь или предложения.

Спасибо.

6
задан James213 25 July 2012 в 20:25
поделиться