У меня есть ошибка, которую я пытаюсь отследить уже несколько недель, и я почти полностью изолировал, что происходит не так. Однако, почему это происходит, мне не под силу.
У меня очень большой пакет Oracle (около 4100 строк кода), и я вызываю несколько процедур. Однако данные, похоже, теряются между вызовами процедур.
Потерянные данные:
dpmethodstate varchar_state_local_type;
Сначала я называю эту процедуру:
PROCEDURE delivery_plan_set_state (
messages OUT ReferenceCursor,
state IN varchar_state_local_type
) AS
BEGIN
logMessage('state COUNT is: ' || state.COUNT);
dpmethodstate := state;
FOR I IN 1..dpmethodstate.COUNT LOOP
logMessage(dpmethodstate(I));
END LOOP;
logMessage('delivery_plan_set_state end - dpmethodstate count is now ' || dpmethodstate.COUNT);
OPEN messages FOR SELECT * FROM TABLE(messageQueue);
messageQueue := NULL;
END delivery_plan_set_state;
Я передаю в состояние, которое является допустимым массивом из одной строки. Я могу проверить в журналах, что dpmethodstate
имеет COUNT
из 1
, когда процедура заканчивается.
Далее я вызываю execute_filter
процедуру, которая выглядит следующим образом:
PROCEDURE execute_filter (
--Whole bunch of OUT parameters
) AS
--About 50 different local variables being set here
BEGIN
SELECT TO_CHAR(SYSTIMESTAMP, 'HH24:MI:SS.ff') INTO TIMING FROM DUAL;
logMessage('[' || TIMING || '] execute_filter begin');
logMessage('a) dpmethodstate Count is: ' || dpmethodstate.COUNT);
--Rest of procedure
Однако на этот раз dpmethodstate.COUNT
равно 0
. Значение, которое я установил с delivery_plan_set_state
, исчезло!
Когда я смотрю на мои журналы, это выглядит примерно так:
proposed
delivery_plan_set_state end - dpmethodstate count is now 1
[21:39:48.719017] execute_filter begin
a) dpmethodstate Count is: 0
Как видите, dpmethodstate
потерялся между вызовами процедур. Есть несколько вещей, на которые стоит обратить внимание:
- Ничто другое в этом пакете не способно установить значение для
dpmethodstate
, кроме delivery_plan_set_state
. И я вижу, что больше никто не назвал это.
- Мой код на стороне клиента написан на C #, и между двумя вызовами процедур мало что происходит.
- Это случается, вероятно, 1 из каждых 100 раз, поэтому очень трудно отследить или отладить.
Во-первых, каков наилучший способ устранения проблемы, подобной этой? Могу ли я сделать еще какие-нибудь записи? Кроме того, как Oracle поддерживает состояние между вызовами процедур и есть ли что-нибудь, что может периодически сбрасывать это состояние? Любые указатели будут высоко оценены!