这两段代码有什么区别?
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;
Run Code Online (Sandbox Code Playgroud)
和...
CURSOR v_my_cur(p_parameter VARCHAR2) IS
SELECT SomeTableID
FROM MYSCHEMA.SOMETABLE
WHERE SomeTableField = p_parameter;
OPEN presf_cur(p_subscriber_id);
Run Code Online (Sandbox Code Playgroud)
他们似乎都工作.它们是相同的还是我应该注意到的一些差异?
第二个示例是显式游标,它是静态的.也就是说,它是一个与一个SQL语句关联的变量.有一个隐含的等价物......
FOR lrec in ( SELECT SomeTableID
FROM MYSCHEMA.SOMETABLE
WHERE SomeTableField = p_parameter )
LOOP
do_something_with (lrec.sometableid);
END LOOP;
Run Code Online (Sandbox Code Playgroud)
第一个例子是一个引用游标,它是一个指向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;
Run Code Online (Sandbox Code Playgroud)
甚至:
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;
Run Code Online (Sandbox Code Playgroud)
因此,使用引用游标可以让我们更好地控制执行的最终SQL语句.另一个区别是,因为引用游标是一个指针,它可以在程序之间传递.这对于将数据从PL/SQL传递到其他语言(例如JDBC结果集)非常有用.