因此,我有一個名爲IDX_ATS_CALC_END_TIME的索引表。該列是時間戳值。此列還具有一個觸發器,可在填充或更新另一個列(Interval_duration)時自動填充列。獲取原因(ORA-8102「索引鍵未找到」)
觸發低於:
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列來修改此列時,我將此錯誤拋出:
ORA-08102: index key not found,obj#97523,file 4,block 244(2)
所提到的索引是基於函數的索引。在索引上使用的函數是calc_end_time列上的sys_extract_utc。
我花了好幾天試圖解決這個問題。我已經重建了索引,我嘗試刪除並重新創建索引。這兩個似乎是這個問題的常見答案,但它們並不適合我。 我使用下面的分析指標:
ANALYZE INDEX IDX_ATS_CALC_END_TIME VALIDATE STRUCTURE;
和它回來了,沒有任何問題。
我唯一能夠成功更新此列而不會出現此錯誤的時間是禁用觸發器,執行更新,然後再次啓用觸發器。這對我來說不是一個可行的解決方案。
所以我想知道是否有人遇到這種類型的問題,以及我可以嘗試修復這個錯誤的其他步驟。
UPDATE: 下面你會發現功能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;
這是寫的我的前任,但基本上它的作用是把給定的數字值,並將其轉換成間隔值。
任何幫助或建議,非常感謝。
謝謝。
可以簡化的功能:'回報seconds_in *(間隔 '1' 秒);'? –
您的索引'IDX_ATS_CALC_END_TIME'的定義是什麼?這是一個基於函數的索引嗎? –
http://docs.oracle.com/cd/E11882_01/server.112/e17766/e7500.htm#sthref2691表明,這可能是一個錯誤。雖然Saurabh的答案表明它可以基於基於非確定性函數的基於函數的索引發生。 –