2016-10-28 13 views
0

Я создал процедуру в базе данных оракула, которая возвращает данные в рефлекторе, и я хочу, чтобы он возвращал строку этого курсора и в качестве выходной переменной. После тестирования переменная P_count заполняется правильно, но когда я попытался открыть курсор, выдается сообщение об ошибке «ORA-01002: fetch out of sequence». Я прочитал ранее об этом, и я обнаружил, что проблема в том, что я использую оператор fetch в своем коде. Но до сих пор я не узнал, как его решить. Любые помощь приветствуются, спасибо. Ниже моя процедура:ORA-01002: выборка из последовательности

PROCEDURE IS_CLIENT_LOGGED_IN (
    P_CLIENT_NUM Varchar2, 
    P_CURSOR out SYS_REFCURSOR , 
    P_COUNT OUT NUMBER, 
    P_ERROR out Varchar2 
) AS 
    cur_rec Varchar2(1024); 
BEGIN 
    BEGIN 
    Open P_CURSOR FOR 
     SELECT ID 
     FROM tbl_registration 
     WHERE tbl_client_id = P_CLIENT_NUM 
      AND tbl_logout_date is null; 

    LOOP 
     FETCH P_CURSOR INTO cur_rec; 
     EXIT WHEN P_CURSOR%notfound; 
     P_COUNT := P_CURSOR%rowcount;--will return row number beginning with 1 
    END LOOP; 
    EXCEPTION WHEN OTHERS THEN 
    P_ERROR := 'Unable to select Data from tbl_registration' ||SQLERRM; 
    END;  
END IS_CLIENT_LOGGED_IN; 
+1

Вы должны закрыть курсор после его использования. –

+1

Какова цель вашей процедуры? Обычно, когда вы возвращаете 'SYS_REFCURSOR', записи записываются вызывающим блоком. Вы не должны возвращать курсор, если строки уже загружены. –

+0

Эта процедура реализована в другом: поэтому мне нужна строка, чтобы возвращать счетчик для циклизации в другой процедуре и курсор для работы с извлеченными данными также в другой процедуре. Когда я добавлял CLOSE P_CURSOR до LOOP, курсор не мог быть определен во время цикла, но когда я добавил после END LOOP, он возвратил дескриптор инструкции ORA-24338, который не был выполнен. Спасибо @WernfriedDomscheit –

ответ

0

Основываясь на ваш комментарий процедура должна выглядеть так:

PROCEDURE IS_CLIENT_LOGGED_IN (
    P_CLIENT_NUM Varchar2, 
    P_CURSOR out SYS_REFCURSOR , 
    P_COUNT OUT NUMBER, 
    P_ERROR out Varchar2 
) AS 
    cur_rec Varchar2(1024); 
BEGIN 
    Open P_CURSOR FOR 
     SELECT ID 
     FROM tbl_registration 
     WHERE tbl_client_id = P_CLIENT_NUM 
      AND tbl_logout_date is null; 

    LOOP 
     FETCH P_CURSOR INTO cur_rec; 
     EXIT WHEN P_CURSOR%notfound; 
     P_COUNT := P_CURSOR%rowcount;--will return row number beginning with 1 
    END LOOP; 
    CLOSE P_CURSOR; 

    Open P_CURSOR FOR 
     SELECT ID 
     FROM tbl_registration 
     WHERE tbl_client_id = P_CLIENT_NUM 
      AND tbl_logout_date is null; 

    EXCEPTION WHEN OTHERS THEN 
    P_ERROR := 'Unable to select Data from tbl_registration' ||SQLERRM; 
END IS_CLIENT_LOGGED_IN; 

не очень эффективным, но это то, что вы просили. Во всяком случае, я не вижу причин увеличивать P_COUNT один за другим.

Сделать

SELECT COUNT(*) INTO P_COUNT 
    FROM tbl_registration 
    WHERE tbl_client_id = P_CLIENT_NUM 
     AND tbl_logout_date is null; 

Open P_CURSOR FOR 
    SELECT ID 
    FROM tbl_registration 
    WHERE tbl_client_id = P_CLIENT_NUM 
     AND tbl_logout_date is null; 

, чтобы получить то же самое.

+0

На самом деле я пытался избежать двух выборов и получить результат из одного выбора, посчитав строки курсора, в любом случае спасибо @Wernfried Domscheit –

Смежные вопросы