【问题标题】:Novice to DB - Oracle数据库新手 - Oracle
【发布时间】:2017-10-06 02:50:10
【问题描述】:

我对 Oracle 和数据库还很陌生。

我正在尝试使用游标编写存储过程。如何在游标循环内编写 select 语句,以及如何遍历从该游标循环内的 select 获得的结果集?

例如:

    Open Curs1;
    Exit When Curs1%NotFound;
    Loop
       Select column1,column2  from table -- Returns multiple records. How to loop through this record set and perform CRUD operations.
    End loop;
    Close Curs1;

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    使用 FOR 循环游标 - 它们比打开/获取/关闭语法更快、更简单。

    begin
        for results1 in
        (
            select ...
        ) loop
            --Do something here
            for results2 in
            (
                select ...
                where some_table.some_column = results1.some_column
            ) loop
                --Do something here
            end loop;
        end loop;
    end;
    /
    

    虽然这从字面上回答了这个问题,但您通常不希望在这样的循环内有循环。如果可能的话,最好将两个 SQL 语句用一个连接组合起来,然后循环遍历结果。

    【讨论】:

      【解决方案2】:

      尝试使用以下示例,从游标变量 emp_cv 一次获取一行到用户定义的记录 emp_rec:

      declare
         TYPE YourType IS ref cursor return YourTable%rowtype;
         tab_cv  YourType;
         tab_rec YourTable%rowtype;
      begin
         loop
            fetch tab_cv into emp_rec;
            exit when tab_cv%notfound;
            ...
         end loop;
      end;
      

      BULK COLLECT 子句允许您从结果集中获取整个列,或一次获取整个结果集中。以下示例从游标中检索列到集合中:

      declare
         type NameList IS table of emp.ename%type;
         names NameList;
         cursor c1 is select ename from emp where job = 'CLERK';
      begin
         open c1;
         fetch c1 bulk collect into names;
         ...
         close c1;
      end;
      

      以下示例使用 LIMIT 子句。在循环的每次迭代中,FETCH 语句将 100 行(或更少)提取到按索引表 acct_ids 中。之前的值会被覆盖。

      declare
         type NumList is table of number index by binary_integer;
         cursor c1 is select acct_id from accounts;
         acct_ids NumList;
         rows natural := 100;  -- set limit
      begin
         open c1;
         loop
            /* The following statement fetches 100 rows (or less). */
            fetch c1 bulk collect into acct_ids limit rows;
            exit when c1%notfound;
            ...
         end loop;
         close c1;
      end;
      

      【讨论】:

        【解决方案3】:

        您需要在循环中声明CURSORFETCH 记录。

        DECLARE
        CURSOR  curs1
        IS
          SELECT column1,
                 column2
          FROM   yourtable;
        
          v_column1 yourtable.column1%TYPE;
          v_column2 yourtable.column2%TYPE;
        BEGIN
         OPEN curs1;
          LOOP
        
            FETCH curs1
            INTO  v_column1,
                  v_column2;
          EXIT
          WHEN curs1%NOTFOUND;
        
            INSERT INTO yourtable2(col1)VALUES( '000'||v_column1  ); 
            -- A sample DML operation.
        
            --Do other operations on individual records here.
          END LOOP;
          CLOSE curs1; 
        END;
        

        【讨论】:

        • 你缺少'open curs1',应该先获取,然后在curs1%notfound时使用exit。
        • 谢谢!这是编辑错误,未经测试...:)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-19
        • 1970-01-01
        • 1970-01-01
        • 2016-01-02
        • 2020-11-24
        • 1970-01-01
        相关资源
        最近更新 更多