0

IN my oracle database i want to create a function or procedure with cursor which will use dynamic table name.here is my code.

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;

help me to solve this problem.IN

2
  • What is your problem? Do you get errors? And rowid is reserved in oracle, use some other alias name. Commented Oct 18, 2012 at 14:12
  • I got error employee_rec not defiend.now i edit in my code, i declare TYPE employee_rec IS REF CURSOR; but after that it shows "Invalid reference to variable 'employee_rec '" Commented Oct 18, 2012 at 14:26

2 Answers 2

2
  • There is no need to declare a c1 type for a weakly typed ref cursor. You can just use the SYS_REFCURSOR type.
  • You can't mix implicit and explicit cursor calls like this. If you are going to OPEN a cursor, you have to FETCH from it in a loop and you have to CLOSE it. You can't OPEN and CLOSE it but then fetch from it in an implicit cursor loop.
  • You'll have to declare a variable (or variables) to fetch the data into. I declared a record type and an instance of that record but you could just as easily declare two local variables and FETCH into those variables.
  • ROWID is a reserved word so I used ROWPOS instead.

Putting that together, you can write something like

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.

I believe this returns the result you expect

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

Note that from an efficiency standpoint, you'd be much better off writing this as a single SQL statement rather than opening a cursor and fetching every row from the table every time. If you are determined to use a cursor, you'd want to exit the cursor when you've found the row you're interested in rather than continuing to fetch every row from the table.

From a code clarity standpoint, many of your variable names and data types seem rather odd. Your parameter names seem poorly chosen-- I would not expect model_in to be the name of the input table, for example. Declaring a cursor named c2 is also problematic since it is very non-descriptive.

Sign up to request clarification or add additional context in comments.

Comments

0

You can do this, you don't need loop when you are using dynamic query

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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.