sql >> Database >  >> RDS >> Oracle

orakelfunctie en cursor met dynamische tabelnaam

  • Het is niet nodig om een ​​c1 . aan te geven type voor een zwak getypte ref-cursor. U kunt gewoon de SYS_REFCURSOR . gebruiken typ.
  • Je kunt op deze manier geen impliciete en expliciete cursoraanroepen combineren. Als u naar OPEN gaat een cursor, moet u FETCH ervan in een lus en je moet CLOSE het. Je kunt niet OPEN en CLOSE het maar haal het er dan uit in een impliciete cursorlus.
  • Je moet een variabele (of variabelen) declareren om de gegevens in op te halen. Ik heb een recordtype en een instantie van dat record gedeclareerd, maar je kunt net zo goed twee lokale variabelen declareren en FETCH in die variabelen.
  • ROWID is een gereserveerd woord, dus ik gebruikte ROWPOS in plaats daarvan.

Als je dat samenvoegt, kun je zoiets schrijven als

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.

Ik geloof dat dit het verwachte resultaat oplevert

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

Houd er rekening mee dat u vanuit het oogpunt van efficiëntie veel beter af bent om dit als een enkele SQL-instructie te schrijven in plaats van een cursor te openen en elke rij elke keer uit de tabel op te halen. Als u vastbesloten bent om een ​​cursor te gebruiken, wilt u de cursor verlaten wanneer u de rij hebt gevonden waarin u geïnteresseerd bent, in plaats van elke rij uit de tabel te blijven halen.

Vanuit het oogpunt van de duidelijkheid van de code lijken veel van uw variabelenamen en gegevenstypen nogal vreemd. Je parameternamen lijken slecht gekozen -- ik zou model_in niet verwachten om bijvoorbeeld de naam van de invoertabel te zijn. Een cursor met de naam c2 . declareren is ook problematisch omdat het erg niet-beschrijvend is.



  1. Wat is het verschil tussen geneste array en associatieve array?

  2. Hoe een bepaalde Node-naam en zijn waarden in XML selecteren met behulp van Oracle SQL-query?

  3. Uitvoeringsvolgorde in MySQL

  4. Een nieuwe kolom toevoegen in alle mysql-tabellen