2009-05-03 5 views
1

Я следующий оракул хранимая процедураКак работают хранимые процедуры оракула (w/cursors)?

CREATE OR REPLACE 
PROCEDURE getRejectedReasons 
    (
    p_cursor IN OUT SYS_REFCURSOR) 
AS 
BEGIN 
    OPEN p_cursor FOR SELECT * FROM reasons_for_rejection; 
END; 

Однако, когда я запускаю эту хранимую процедуру в SQL-разработчика, то я не вижу ничего. Я просто вижу что-то вроде этого:

Connecting to the database oracleLocal. 
Process exited. 
Disconnecting from the database oracleLocal. 

Иду с сервера SQL MS, и я привык видеть реальные результаты при выполнении хранимой процедуры, как это. Эта хранимая процедура не возвращает результаты, потому что я использую курсор?

ответ

1

Вы открыли курсор. Вы ничего не выбрали из него, не обновили или не продвинули.

Все открытые эффективно, чтобы выбрать соответствующие строки во временную память, чтобы вы могли перемещать курсор подряд за строкой. Которых вы не делали.

+0

как я могу «заранее» курсор, чтобы он показывал мне результаты, когда я его выполняю. – 2009-05-03 17:01:58

+0

Ну, нет. То есть, вся точка курсора состоит в том, чтобы указать одну строку за раз, а не целый набор результатов из множества строк. Вы можете перебрать его с помощью «для rec в петле p_cursor» «end loop;» – tpdi

+0

ok, я буду использовать эту хранимую процедуру в файле iBatis с java-кодом. Так что я думаю, что я могу получить весь курсор, а затем зациклиться на нем – 2009-05-03 17:33:38

0

Одно из различий между Oracle и SQL Server является то, что последний возвращает наборы результатов, естественно. Кстати, я бы использовал функцию.

В Oracle функции обычно возвращают один элемент. Позднее появились курсоры.

Там какая-то документация в Интернете, которые помогут вам понять использование REFCURSOR переменных связывания. Вот одна такая для SQL * Plus:

http://download.oracle.com/docs/cd/B19306_01/server.102/b14357/ch5.htm#sthref1122

Я думаю, что в SQL Developer вы можете сделать то же самое с AUTOPRINT на, хотя я не проверял это.

Найдено блог, который также обсуждает что-то подобное:

http://vadimtropashko.wordpress.com/cursors/

+0

Курсор pl/sql - это один элемент, функция pl/sql может возвращать курсор. – tuinstoel

-1

ETA: Хорошо. Игнорируйте то, что я написал. Слушайте кого-то еще. По-видимому, это неправильно, поскольку я проголосовал.

Что, по словам tpdi, является правильным. Вы должны что-то сделать с помощью курсора после его объявления.

Вот пример использования двух курсоров во вложенных циклах

PROCEDURE update_insert_tree (exid_in IN NUMBER, outvar_out OUT VARCHAR2) 
    IS 
     nxtid   NUMBER; 
     phaseid  NUMBER; 
     rowcounter1 NUMBER; 
    BEGIN 
     rowcounter1 := 0; 
     outvar_out := 0; 

     FOR acur IN (SELECT dept_exercise_id, phase 
        FROM ep_dept_exercise 
        WHERE exercise_id = exid_in) 
     LOOP 

     <<dept_loop>> 
     FOR thecur IN (SELECT document_name, thelevel, sortnum, type_flag, 
           ex_save_id 
          FROM ep_exercise_save 
         WHERE exercise_id = exid_in) 
     LOOP 
      phaseid := acur.phase; 

      IF phaseid = 0 
      THEN 
       phaseid := 10; 

       UPDATE ep_dept_exercise 
        SET phase = 10 
       WHERE dept_exercise_id = acur.dept_exercise_id; 
      END IF; 

      <<doc_loop>> 
5

Хранимая процедура возвращает что-то это просто вы ничего не делаете с результатами.

Вы можете сделать это, просто запустив следующий скрипт в SQLDeveloper:


VARIABLE csr REFCURSOR; 
EXEC getRejectedReasons(:csr); -- the colon identifies the parameter as a variable 
PRINT csr; 

Другой метод выборки каждой строки и сделать какую-то обработку:


DECLARE 
    -- sys_refcursor is weakly typed 
    refcsr SYS_REFCURSOR; 
    -- define a record so we can reference the fields 
    rej_rec Reasons_for_Rejection%ROWTYPE; 
BEGIN 

    getRejectedReasons(refcsr); 

    -- loop through the results 
    LOOP 
     -- gets one row at a time 
     FETCH refcsr INTO rej_rec; 
     -- if the fetch doesn't find any more rows exit the loop 
     EXIT WHEN refcsr%NOTFOUND; 
     -- Do something here. 
     -- For example : DBMS_OUTPUT.PUT_LINE(rej_rec.reason_desc); 
    END LOOP; 

END;