sql >> Databasteknik >  >> RDS >> Oracle

orakelfunktion och markör med dynamiskt tabellnamn

  • Det finns inget behov av att deklarera en c1 skriv för en svagt skriven ref-markör. Du kan bara använda SYS_REFCURSOR typ.
  • Du kan inte blanda implicita och explicita marköranrop så här. Om du ska OPEN en markör måste du FETCH från den i en slinga och du måste CLOSE Det. Du kan inte OPEN och CLOSE den men hämta sedan från den i en implicit markörslinga.
  • Du måste deklarera en variabel (eller variabler) för att hämta data till. Jag deklarerade en posttyp och en instans av den posten men du kan lika gärna deklarera två lokala variabler och FETCH i dessa variabler.
  • ROWID är ett reserverat ord så jag använde ROWPOS istället.

Om du sätter ihop det kan du skriva något i stil med

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.

Jag tror att detta ger det resultat du förväntar dig

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

Observera att ur effektivitetssynpunkt skulle du vara mycket bättre att skriva detta som en enda SQL-sats snarare än att öppna en markör och hämta varje rad från tabellen varje gång. Om du är fast besluten att använda en markör, skulle du vilja lämna markören när du har hittat raden du är intresserad av istället för att fortsätta att hämta varje rad från tabellen.

Ur en kodtydlighetssynpunkt verkar många av dina variabelnamn och datatyper ganska udda. Dina parameternamn verkar dåligt valda - jag skulle inte förvänta mig model_in att vara namnet på inmatningstabellen, till exempel. Deklarera en markör som heter c2 är också problematiskt eftersom det är mycket icke-beskrivande.



  1. MySQL-fråga med alias som inte använder ett index

  2. Hur man använder xmlconcat-funktionen i Oracle

  3. Infoga uppdatering lagrad proc på SQL Server

  4. Alias ​​för att visa tabeller MySQL-resultat