Каково различие между этими двумя частями кода?
TYPE t_my_cursor IS REF CURSOR;
v_my_cursor t_my_cursor;
OPEN v_my_cursor FOR SELECT SomeTableID
FROM MYSCHEMA.SOMETABLE
WHERE SomeTableField = p_parameter;
И...
CURSOR v_my_cur(p_parameter VARCHAR2) IS
SELECT SomeTableID
FROM MYSCHEMA.SOMETABLE
WHERE SomeTableField = p_parameter;
OPEN presf_cur(p_subscriber_id);
Они оба, кажется, работают. Действительно ли они - то же или есть ли некоторое различие, о котором я должен знать?
Второй пример - это явный курсор, и он статичен. То есть, это переменная, связанная с одним оператором SQL. Существует неявный эквивалент...
FOR lrec in ( SELECT SomeTableID
FROM MYSCHEMA.SOMETABLE
WHERE SomeTableField = p_parameter )
LOOP
do_something_with (lrec.sometableid);
END LOOP;
Первый пример - это рефлексивный курсор, который является указателем на SQL-запрос и поэтому может быть динамическим. Например, мы можем расширить этот пример следующим образом:
TYPE t_my_cursor IS REF CURSOR;
v_my_cursor t_my_cursor;
...
if flag = 1 then
OPEN v_my_cursor FOR SELECT SomeTableID
FROM MYSCHEMA.SOMETABLE
WHERE SomeTableField = p_parameter;
else
OPEN v_my_cursor FOR SELECT SomeTableID
FROM MYSCHEMA.ANOTHERTABLE
WHERE AnotherTableField = p_parameter;
end if;
Или даже:
l_stmt := 'SELECT * FROM your_table WHERE ';
if p_parameter is not null then
l_stmt := l_stmt ||'id = :1';
open v_my_cursor for l_stmt using p_parameter;
else
l_stmt := l_stmt ||'created_date > trunc(sysdate)';
open v_my_cursor for l_stmt;
end if;
Таким образом, использование ref-курсора дает нам гораздо больше контроля над конечным SQL-оператором, который будет выполнен. Другое отличие заключается в том, что, поскольку ref-курсор является указателем, его можно передавать между программами. Это очень полезно для передачи данных из PL/SQL в другие языки, например, в набор результатов JDBC.