2017-10-06 5 views
1

私はOracleとDatabaseのかなり新しいです。初心者からDBへ - 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; 

答えて

0

あなたがループ内でCURSORFETCHレコードを宣言する必要があります。

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 
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; 
+0

'open curs1'がありません。最初にフェッチし、curs1%notfoundのときにexitを使用してください。 –

+0

ありがとう!間違いを修正していて、テストされていない... –

0

てみてくださいは、ユーザー定義のレコードEMP_RECにカーソル変数emp_cvから一度に行1を取り出し、次の例を使用するには結果セットのすべての列、または結果セット全体を一度に取得できます。次の例では、コレクションにカーソルから列を取得:

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文は索引付き表acct_idsに100行(またはそれ以下)をフェッチします。以前の値は上書きされます。

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; 
2

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; 
/

これは文字通り答えますが、一般的にこのようなループ内にループを持つことは望ましくありません。可能であれば、2つのSQLステートメントを結合して結合し、結果をループするほうがよいでしょう。

関連する問題