Oracle11g 使用动态表名的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

在我的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 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”的无效引用