Итак, у меня есть таблица с индексом с именем 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;
это было написано моим предшественником, но в основном все, что она делает, это превращает заданное числовое значение и преобразует его в значение интервала.
Будем признательны за любую помощь или предложения.
Спасибо.