如何将游标的SELECT查询转换为在PL / SQL存储过程中完全运行?

时间:2019-08-06 13:11:31

标签: oracle stored-procedures plsql plsqldeveloper

我想知道我是否可以优化Oracle 12中的存储过程。它以OUT游标的形式返回几个查询结果。我以为可以使用Allround PL / SQL Developer中的Profile工具对过程进行概要分析,但是我意识到执行该过程不会评估(遍历)输出游标,因此我的概要文件不会给我带来任何有趣的印象。

如何修改存储过程以完全评估游标?在SQL Server中,该过程中可能只包含裸露的SELECT语句,但看起来在PL / SQL过程中是不可能的。 如何修改游标的SELECT查询的PL / SQL以完全评估PL / SQL存储过程中的SELECT ,以便可以对过程进行整体分析?

相对于SQL Server,我认为我正在与Oracle范式作斗争,因此,如果我考虑此错误,不妨听听它。

    CREATE OR REPLACE PROCEDURE sp_my_proc(
        /* ... */
        out_my_cursor OUT SYS_REFCURSOR) IS 
    BEGIN 
        /* ... */
        OPEN out_my_cursor FOR
        SELECT ... FROM ... ; -- I want to profile this whole proc including this SELECT
    END sp_my_proc;

1 个答案:

答案 0 :(得分:1)

这是一个最小的示例,如何在PL / SQL中从返回的游标中获取所有行。

添加输入参数和游标中返回的其他列

CREATE OR REPLACE PROCEDURE sp_my_proc(
    out_my_cursor OUT SYS_REFCURSOR) IS 
BEGIN 
    OPEN out_my_cursor FOR
    SELECT rownum ID FROM dual connect by level <= 5; 
END sp_my_proc;
/    


declare
cv_out sys_refcursor; 
--  
v_id   NUMBER;
begin
         sp_my_proc(cv_out);
         /* to read the cursor use fetch in a loop */
         LOOP
            FETCH cv_out INTO v_id;
            EXIT WHEN cv_out%NOTFOUND;
            dbms_output.put_line( 'ID= '|| v_ID   ); 
        END LOOP;       
end;
/  

从游标中获取行时,主要困难在于在FETCH INTO子句中定义变量。

Oracle提供了两个选项来简化此任务。

如果光标列与表或视图1:1对应,则可以使用table_or_view_name%ROWTYPE

示例

v_cur   tab%ROWTYPE;
BEGIN 
    OPEN out_my_cursor FOR
    SELECT col1, col2 FROM tab;  /* tab has two columns */

更多可能需要一般情况的cursor%ROWTYPE

但是不幸的是,它不能与动态游标一起使用,因此必须显式声明游标(从过程中复制它)

declare
 CURSOR cur is
    SELECT col1, col2 FROM tab;  /* tab has more than two columns */
 v_cur cur%ROWTYPE;
begin
         OPEN cur;
         LOOP
            FETCH cur INTO v_cur;
            EXIT WHEN cur%NOTFOUND;
             dbms_output.put_line( 'col1= '|| v_cur.col1   );
         END LOOP;       
end;
/ 
相关问题