În loc să executați imediat întreaga interogare, este posibilă configurarea cursorului încapsulând interogarea și apoi obținerea rezultatului interogării de mai multe ori la un moment dat. Un motiv pentru a face acest lucru este de a evita depășirea memoriei atunci când rezultatul conține un număr mare de rânduri. (Utilizatorii PL / pgSQL nu trebuie să vă faceți griji cu privire la acest lucru, deoarece pentru buclele utiliza în mod automat un cursor pentru a evita problemele de memorie.) O opțiune mai interesantă este utilizarea funcției returnează o referință la un cursor care permite apelantului pentru a obține șirul de interogare. Aceasta este o modalitate eficientă de a obține seturi mari de șiruri de funcții.
(Pentru compatibilitatea cu Oracle, FOR poate fi înlocuit cu IS.) Dacă specificați SCROLL, cursorul poate fi derulat înapoi. Cu NO SCROLL nu este permisă derularea înapoi. Dacă nu este specificat nimic, abilitatea de a derula înapoi depinde de cerere. Dacă sunt specificate argumente. atunci acestea trebuie să fie perechi de nume de tip de date. separate prin virgule. Aceste perechi definesc numele care vor fi înlocuite de valorile parametrilor din această interogare. Valorile reale pentru înlocuirea acestor nume vor apărea mai târziu când cursorul este deschis.
Toate cele trei variabile au tipul de date refcursor. Primul poate fi folosit cu orice interogare, cel de-al doilea este legat de interogarea complet formată, iar cea de-a doua este asociată cu interogarea parametrizată. (cheia va fi înlocuită cu o valoare a parametrului întreg atunci când cursorul este deschis.) Variabila curs1 se spune că este nelegată, deoarece nu este legată nici o interogare.
Înainte de a obține linia de pe cursor, trebuie să o deschideți. (Aceasta este echivalentă cu comanda DECLARE CURSOR SQL.) În PL / pgSQL, există trei forme ale instrucțiunii OPEN. două dintre acestea fiind utilizate pentru variabilele cursor neconsolidate, iar a treia pentru cele conexe.
Notă: variabilele cursor asociate pot fi utilizate cu o buclă FOR fără a deschide în mod explicit cursorul, așa cum este descris în Subsecțiunea 40.7.4.
40.7.2.1. Deschidere pentru cerere
Variabila cursorului se deschide și primește o cerere specifică de execuție. Cursorul nu poate fi deja deschis, iar variabila cursorului trebuie să fie nelegată (adică doar o variabilă de tip refcursor). Cererea trebuie să fie o instrucțiune SELECT sau orice altul care returnează un șir (de exemplu EXPLAIN). Cererea este procesată în același mod ca și alte comenzi SQL din PL / pgSQL. Numele variabilelor PL / pgSQL sunt înlocuite cu valori, planul interogării este stocat în cache pentru reutilizare. Înlocuirea valorilor variabilelor PL / pgSQL se face la deschiderea cursorului prin comanda OPEN. modificările ulterioare ale valorilor variabilelor nu afectează funcționarea cursorului. SCROLL și NO SCROLL au același înțeles ca pentru cursorul asociat.
40.7.2.2. DESCHIDE PENTRU EXECUT
Variabila cursorului este deschisă și primește o cerere specifică de execuție. Cursorul nu poate fi deja deschis și trebuie declarat ca o variabilă cursor liber (adică, pur și simplu reflexorul variabil). Interogarea este specificată printr-o expresie de șir, la fel ca în comanda EXECUTE. Ca de obicei, acest lucru face posibilă modificarea flexibilă a planului de interogare din timp în timp (a se vedea Subsecțiunea 40.10.2). Acest lucru înseamnă, de asemenea, că variabilele nu sunt înlocuite în linia de comandă însăși. Ca și EXECUTE. Valorile parametrilor sunt introduse în comanda dinamică utilizând formatul () și UTILIZAREA. Parametrii SCROLL și NO SCROLL acționează aici în același mod ca și cu cursorul asociat.
În acest exemplu, numele tabelului este inserat în textul interogării utilizând formatul (). O valoare care este comparată cu col1. se introduce folosind parametrul USING. astfel încât nu este necesar să-l închidem în apostrofuri.
Când treceți valorile argumentului, puteți utiliza o notație pozițională sau nominală. În notația pozițională, toate argumentele sunt enumerate în ordine. În notație nominală, numele fiecărui argument este separat de expresia argumentului folosind: =. Acest lucru este similar cu apelul pentru funcții descris în secțiunea 4.3. De asemenea, este permisă amestecarea notațiilor poziționale și nominale.
Exemple (se folosesc cursoarele declarate anterior):
Deoarece există o substituire a valorilor variabile pentru cursorul asociat, există, de fapt, două modalități de a transmite valori cursorului. Sau folosiți argumente explicite în DESCHIS. sau implicit, referindu-se la variabilele PL / pgSQL din interogare. Într-un cursor conectat, puteți face referire numai la variabilele care au fost declarate înaintea cursorului. În ambele cazuri, valoarea variabilei care urmează să fie substituită în interogare va fi determinată în momentul OPEN. Iată un alt mod de a obține același rezultat cu curs3. ca în exemplul de mai sus:
După ce ați deschis cursorul, puteți lucra cu acesta folosind operatorii descriși aici.
Nu este necesar să lucrați cu cursorul în aceeași funcție în care a fost deschisă. Din funcție, puteți returna o valoare cu tipul refcursorului. Acest lucru va permite apelantului să continue să lucreze cu cursorul. (Inside string refcursor este un nume convențional așa-numitul portal care conține interogarea cursorului activ. Este posibil să se transmită numele, atribuiți alte variabile de tip refcursor și așa mai departe, în care portalul nu este încălcat).
Toate portalurile sunt închise implicit la sfârșitul tranzacției. Prin urmare, valoarea refcursorului poate fi utilizată pentru a se referi la cursorul deschis doar până la sfârșitul tranzacției.
40.7.3.1. FETCH
FETCH extrage următoarea linie de la cursor la ținta. Ținta poate fi o variabilă de șir, o variabilă de tip de înregistrare. sau o listă de variabile simple separate prin virgulă, ca în SELECT INTO. Dacă nu există următoarea linie, ținta este NULL. Ca și în SELECT INTO. Pentru a verifica dacă înregistrarea a fost obținută utilizând variabila specială FOUND.
Valoarea direcției poate fi orice opțiune în comanda SQL FETCH, cu excepția celor care recuperează mai mult de o linie. Anume: NEXT. PREALABILĂ. PRIMUL. ULTIMA. Număr ABSOLUT. Numărul RELATIV. FORWARD sau BACKWARD. Fără a indica direcția, se folosește valoarea NEXT. Valori de direcție. care necesită deplasarea înapoi va duce la o eroare dacă cursorul nu este declarat sau deschis cu indicația SCROLL.
cursorul este o variabilă de tip refcursor. care se referă la un portal cursor deschis.
40.7.3.2. MOVE
MOVE mișcă cursorul fără a extrage date. MOVE funcționează la fel ca FETCH. dar doar mută cursorul și nu extrage linia la care sa mutat. Ca și în SELECT INTO. Pentru a verifica succesul mișcării, puteți utiliza variabila specială FOUND.
Aici direcția poate fi orice opțiune în opțiunea FETCH a comenzii SQL, și anume: NEXT. PREALABILĂ. PRIMUL. ULTIMA. Număr ABSOLUT. Numărul RELATIV. ALL. FORWARD [număr ALL] sau BACKWARD [număr | ALL]. Fără a indica direcția, se folosește valoarea NEXT. Valori de direcție. care necesită deplasarea înapoi va duce la o eroare dacă cursorul nu este declarat sau deschis cu indicația SCROLL.
40.7.3.3. UPDATE / DELETE ÎN CAZUL CURENTULUI
Când cursorul este poziționat pe un rând de masă, această linie poate fi modificată sau ștersă cu ajutorul cursorului. Există limitări în ceea ce privește solicitarea cursorului (în special, nu ar trebui să existe grupări) și este foarte de dorit să utilizați instrucțiunea FOR UPDATE. Pentru mai multe informații, consultați pagina de ajutor DECLARE.
40.7.3.4. ÎNCHIS
CLOSE închide portalul asociat cu cursorul. Folosit pentru a elibera resurse înainte de încheierea tranzacției sau pentru a elibera din nou variabila cursorului.
Cursorii pot fi returnați de la o funcție la PL / pgSQL. Acest lucru este util când trebuie să reveniți la mai multe rânduri și coloane, mai ales dacă eșantioanele sunt foarte mari. Pentru aceasta, funcția deschide cursorul și numele său este returnat apelantului (sau cursorul este deschis pur și simplu utilizând numele de portal specificat, cumva cunoscut de apelant). Apelantul poate recupera rândurile de la cursor. Cursorul poate fi închis de către apelant sau va fi închis automat când tranzacția este finalizată.
Numele portalului utilizat pentru cursor poate fi specificat de dezvoltator sau va fi generat automat. Pentru a specifica numele portalului, trebuie doar să atribuiți un șir reflexorului variabil înainte de ao deschide. Valoarea reflexorului de variabile de șir va fi folosită de comanda OPEN ca nume de portal. Cu toate acestea, dacă variabila reflexor este NULL, OPEN generează automat un nume care nu contravine nici unui portal existent și îl atribuie reflexorului variabil.
Notă: Variabila cursor asociată este inițializată la o valoare de șir care reprezintă numele variabilei în sine. Astfel, numele portalului coincide cu numele variabilei cursorului, cu excepția cazului în care dezvoltatorul a redefinit numele, atribuind o nouă valoare înainte de a deschide cursorul. Variabila cursorului nelegat este inițializată la NULL și va primi un nume unic generat automat dacă nu este suprascris.
Următorul exemplu prezintă o modalitate de a transmite numele apelantului către apelant:
Următorul exemplu folosește generarea automată a unui nume de cursor:
Următorul exemplu prezintă o modalitate de a returna mai mulți cursori dintr-o funcție:
Una dintre variantele pentru buclă FOR vă permite să sortați liniile returnate de cursor. Aici este sintaxa sa:
Această înregistrare variabilă este definită automat ca o variabilă a înregistrării de tip și există numai în interiorul bucla (alte variabile declarate cu acest nume sunt ignorate în buclă). Fiecare linie returnată de cursor este atribuită acestei variabile și se execută corpul bucla.