Oracle11g 使用动态表名的oracle函数和游标
在我的oracle数据库中,我想用游标创建一个函数或过程,它将使用动态表名Oracle11g 使用动态表名的oracle函数和游标,oracle11g,Oracle11g,在我的oracle数据库中,我想用游标创建一个函数或过程,它将使用动态表名 CREATE OR REPLACE Function Findposition ( model_in IN varchar2,model_id IN number) RETURN number IS cnumber number; TYPE c1 IS REF CURSOR; c2 c1; BEGIN open c2 FOR 'SELECT id,ROW_NUMBER() OVER ( ORDER BY id) AS r
CREATE OR REPLACE Function Findposition ( model_in IN varchar2,model_id IN number) RETURN number IS cnumber number;
TYPE c1 IS REF CURSOR;
c2 c1;
BEGIN
open c2 FOR 'SELECT id,ROW_NUMBER() OVER ( ORDER BY id) AS rownumber FROM '||model_in;
FOR employee_rec in c2
LOOP
IF employee_rec.id=model_id then
cnumber :=employee_rec.rownumber;
end if;
END LOOP;
close c2;
RETURN cnumber;
END;
帮我解决这个问题
不需要为弱类型的ref游标声明c1类型。您可以只使用SYS\u REFCURSOR类型。
不能像这样混合使用隐式和显式游标调用。如果你要打开一个游标,你必须在一个循环中从它取回并关闭它。您不能打开和关闭它,但可以在隐式游标循环中从中提取。
您必须声明一个或多个变量来获取数据。我声明了一个记录类型和该记录的一个实例,但您可以同样轻松地声明两个局部变量并获取这些变量。
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的游标也是有问题的,因为它非常非描述性 您可以做到这一点,在使用动态查询时不需要循环
CREATE OR REPLACE Function Findposition(model_in IN varchar2,model_id IN number)
RETURN number IS
cnumber number;
TYPE c1 IS REF CURSOR;
c2 c1;
BEGIN
open c2 FOR 'SELECT rownumber
FROM (
SELECT id,ROW_NUMBER() OVER ( ORDER BY id) AS rownumber
FROM '||model_in || '
) WHERE id = ' || model_id;
FETCH c2 INTO cnumber;
close c2;
return cnumber;
END;
你有什么问题?你有错误吗?rowid是oracle中保留的,请使用其他别名。我得到错误employee\u rec not defined。现在我在代码中编辑,我声明类型employee\u rec为REF CURSOR;但在此之后,它显示对变量“employee_rec”的无效引用