Выдача записи дисплея в форме оракула 10g

Я новичок в Oracle Form и pl/sql. Вот моя проблема. В моей форме у меня есть 3 блока данных, которые отображают записи, которые я извлекаю из таблицы с именем BOS_M_HOLIDAY. Но почему-то после цикла в каждом блоке данных отображается только последняя запись. Я извлекаю записи с помощью триггера PRE-FORM и триггера WHEN-TIME-EXPIRED. Вот мой код в триггере PRE-FORM:

DECLARE

CURSOR a_aa is SELECT HOL_DATE FROM BOS_M_HOLIDAY WHERE REGEXP_LIKE(HOL_DATE, '.......12') ORDER BY HOL_DATE;
CURSOR a_bb is SELECT HOL_DATE FROM BOS_M_HOLIDAY WHERE REGEXP_LIKE(HOL_DATE, '.......13') ORDER BY HOL_DATE ;
CURSOR a_cc is SELECT distinct DESCR FROM BOS_M_HOLIDAY WHERE REGEXP_LIKE(HOL_DATE, '.......13')ORDER BY 1;
Timer_ID TIMER;

BEGIN

OPEN a_aa;
LOOP
    FETCH a_aa INTO :holiday_2012.HOL_DATE;
    EXIT WHEN a_aa%notfound;
    Timer_ID := FIND_TIMER('CALL_NEXT_RECORD');
        IF NOT Id_Null(Timer_ID) THEN
        Delete_Timer(Timer_ID);
        END IF;
    Timer_ID := Create_Timer('CALL_NEXT_RECORD',1,NO_REPEAT);
END LOOP;
CLOSE a_aa;

OPEN a_bb;
LOOP
    FETCH a_bb INTO :holiday_2013.HOL_DATE;
    EXIT WHEN a_bb%notfound;
    Timer_ID := FIND_TIMER('CALL_NEXT_RECORD');
        IF NOT Id_Null(Timer_ID) THEN
        Delete_Timer(Timer_ID);
        END IF;
    Timer_ID := Create_Timer('CALL_NEXT_RECORD',1,NO_REPEAT);
END LOOP;
CLOSE a_bb;

OPEN a_cc;
LOOP
    FETCH a_cc INTO :description.DESCR;
    EXIT WHEN a_cc%notfound;
    Timer_ID := FIND_TIMER('CALL_NEXT_RECORD');
        IF NOT Id_Null(Timer_ID) THEN
        Delete_Timer(Timer_ID);
        END IF;
    Timer_ID := Create_Timer('CALL_NEXT_RECORD',1,NO_REPEAT);
END LOOP;
CLOSE a_cc;

END;

и вот мой код в триггере WHEN-TIME-EXPIRED:

DECLARE
v_Timer VARCHAR2(30) := Get_Application_Property(TIMER_NAME);
BEGIN
IF (v_Timer = 'CALL_NEXT_RECORD') THEN
    NEXT_RECORD;
END IF;
END;

Этот код работает, когда я использую триггер WHEN-BUTTON-PRESSED без части TIMER. Не стесняйтесь моего английского и не стесняйтесь спрашивать меня, есть ли какие-то части, которые вы не понимаете. Спасибо!


person Khai Kiong    schedule 13.09.2013    source источник


Ответы (1)


В ваших циклах каждая запись назначается одной и той же (1-й) записи в каждом блоке. Конечно, вы создаете таймер, который выдает NEXT_RECORD, но это, безусловно, худшая из возможных идей, и она в любом случае не работает, потому что к моменту фактического выполнения таймера большинство (если не все) ваших циклов уже завершились. В вашем цикле нет ничего, что ждало бы завершения таймера, прежде чем он перейдет к следующей записи - на самом деле, он, вероятно, создает и уничтожает таймер много раз, прежде чем таймер когда-либо получит возможность действительно запуститься!

Не используйте таймеры для такого рода вещей. Вам нужно вызвать NEXT_RECORD внутри вашего цикла.

Кроме того, я бы рекомендовал вам не помещать такой код в PRE-FORM — вместо этого поместите его в свой триггер WHEN-NEW-FORM-INSTANCE.

Более того, вы должны основывать блоки на таблице (поместить предикат в свойство DEFAULT_WHERE) и выполнять запрос вместо использования этого процедурного кода.

person Jeffrey Kemp    schedule 13.09.2013
comment
Спасибо за ответ Джеффри! Причина включения таймера из-за ошибки FRM-40102: Запись должна быть введена или удалена первой. продолжайте всплывать при запуске формы. Теперь код перемещен в триггер WHEN-NEW-FORM-INSTANCE, а таймер удален, но я все еще сталкиваюсь с той же ошибкой, возможно, из-за ограниченного встроенного NEXT_RECORD на уровне формы. - person Khai Kiong; 13.09.2013
comment
Нет ограничений на использование NEXT_RECORD в триггере wnfi. Вы правы, что удалили таймеры. FRM-40102 сообщает вам, что вы пытаетесь перейти к следующей записи до того, как поместите некоторые данные в текущую запись. Я заметил, что у вас нет вызовов GO_BLOCK — это означает, что курсор может находиться в другом блоке, который вы ожидаете. - person Jeffrey Kemp; 13.09.2013
comment
В любом случае, ваш метод заполнения блоков вручную с помощью курсора и цикла является сложным и подвержен ошибкам. Если вы новичок в Forms, это не способ сделать это. Вместо этого вы должны использовать блоки на основе таблиц, как в последней строке моего ответа. - person Jeffrey Kemp; 13.09.2013
comment
Я думаю, я понял тебя, братан! Еще раз спасибо за помощь, хорошего дня :) - person Khai Kiong; 17.09.2013