Oracle
 sql >> Baza danych >  >> RDS >> Oracle

funkcja oracle i kursor przy użyciu dynamicznej nazwy tabeli

  • Nie ma potrzeby deklarowania c1 type dla słabo wpisanego kursora ref. Możesz po prostu użyć SYS_REFCURSOR typ.
  • Nie można mieszać niejawnych i jawnych wywołań kursora w ten sposób. Jeśli zamierzasz OPEN kursor, musisz FETCH z niego w pętli i musisz CLOSE to. Nie możesz OPEN i CLOSE go, ale potem pobiera z niego w niejawnej pętli kursora.
  • Będziesz musiał zadeklarować zmienną (lub zmienne), do której będą pobierane dane. Zadeklarowałem typ rekordu i instancję tego rekordu, ale równie łatwo możesz zadeklarować dwie zmienne lokalne i FETCH do tych zmiennych.
  • ROWID jest słowem zastrzeżonym, więc użyłem ROWPOS zamiast tego.

Łącząc to, możesz napisać coś takiego

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.

Uważam, że to zwraca oczekiwany wynik

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

Zauważ, że z punktu widzenia wydajności znacznie lepiej byłoby napisać to jako pojedyncze polecenie SQL, niż otwierać kursor i za każdym razem pobierać każdy wiersz z tabeli. Jeśli jesteś zdecydowany użyć kursora, wolałbyś wyjść z niego po znalezieniu wiersza, który Cię interesuje, zamiast kontynuować pobieranie każdego wiersza z tabeli.

Z punktu widzenia przejrzystości kodu wiele nazw zmiennych i typów danych wydaje się dość dziwnych. Twoje nazwy parametrów wydają się źle dobrane — nie spodziewałbym się, że model_in być nazwą tabeli wejściowej, na przykład. Deklarowanie kursora o nazwie c2 jest również problematyczny, ponieważ jest bardzo nieopisowy.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Podzapytanie Oracle w słowie kluczowym jest wolne na 12c

  2. jak wypełnić bazę danych za pomocą procedur

  3. Pobieranie wartości zwracanej przez funkcję PL/SQL przez Hibernate

  4. Jak pisać do pliku tekstowego z Pl/SQL, błąd PLS 00363

  5. Klucze podstawowe i indeksy w języku zapytań Hive są poosible czy nie?