c1
弱い型の参照カーソルの型を宣言する必要はありません。タイプだけを使用できますSYS_REFCURSOR
。
- このように、暗黙的なカーソル呼び出しと明示的なカーソル呼び出しを混在させることはできません。
OPEN
カーソルに移動する場合はFETCH
、ループ内でカーソルから移動する必要がありますCLOSE
。できませんがOPEN
、CLOSE
暗黙のカーソルループでフェッチします。
- データをフェッチする変数を宣言する必要があります。レコードタイプとそのレコードのインスタンスを宣言しましたが、2つのローカル変数
FETCH
をそれらの変数に簡単に宣言できます。
ROWID
は予約語なので、ROWPOS
代わりに使用しました。
それをまとめると、次のようなものを書くことができます
SQL> ed
Wrote file afiedt.buf
1 CREATE OR REPLACE Function Findposition (
2 model_in IN varchar2,
3 model_id IN number)
4 RETURN number
5 IS
6 cnumber number;
7 c2 sys_refcursor;
8 type result_rec is record (
9 id number,
10 rowpos number
11 );
12 l_result_rec result_rec;
13 BEGIN
14 open c2 FOR 'SELECT id,ROW_NUMBER() OVER ( ORDER BY id) AS rowpos FROM '||model_in;
15 loop
16 fetch c2 into l_result_rec;
17 exit when c2%notfound;
18 IF l_result_rec.id=model_id
19 then
20 cnumber :=l_result_rec.rowpos;
21 end if;
22 END LOOP;
23 close c2;
24 RETURN cnumber;
25* END;
SQL> /
Function created.
私はこれがあなたが期待する結果を返すと信じています
SQL> create table foo( id number );
Table created.
SQL> insert into foo
2 select level * 2
3 from dual
4 connect by level <= 10;
10 rows created.
SQL> select findposition( 'FOO', 8 )
2 from dual;
FINDPOSITION('FOO',8)
---------------------
4
効率の観点から、カーソルを開いてテーブルからすべての行を毎回フェッチするよりも、これを単一のSQLステートメントとして記述する方がはるかに優れていることに注意してください。カーソルを使用することにした場合は、テーブルからすべての行をフェッチし続けるのではなく、目的の行が見つかったらカーソルを終了することをお勧めします。
コードの明確さの観点から、変数名とデータ型の多くはかなり奇妙に見えます。model_in
パラメータ名の選択が不十分なようです。たとえば、入力テーブルの名前になるとは思いません。名前付きカーソルを宣言するc2
ことも、非常にわかりにくいため、問題があります。