- 不需要
c1
为弱类型引用游标声明类型。你可以只使用SYS_REFCURSOR
类型。
- 您不能像这样混合隐式和显式游标调用。如果你要去
OPEN
一个游标,你必须FETCH
从它循环中,你必须CLOSE
它。你不能OPEN
和CLOSE
它然后在一个隐式游标循环中从中获取。
- 您必须声明一个变量(或多个变量)才能将数据提取到其中。我声明了一个记录类型和该记录的一个实例,但您可以轻松地声明两个局部变量并
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
也是有问题的,因为它非常不具描述性。