Oracle
 sql >> база данни >  >> RDS >> Oracle

функция на oracle и курсор, използващ име на динамична таблица

  • Няма нужда да декларирате 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 също е проблематичен, тъй като е много неописателен.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да отпечатам триъгълник от звезди с помощта на SQL

  2. подпроцес дава грешка. Системата не може да намери посочения файл

  3. Добавяне на оператор IF ELSE

  4. Как да внедрим ora_hash (хеш с възможност за зареждане, който разделя всеки sql тип данни на n кофи)

  5. Как мога да извлека файлове от поле на Oracle BLOB?