Cursoare în procedurile memorate mysql, mysql

Deoarece cursorii fac parte din procedura stocată, în acest articol vom examina mai detaliat HP. În special, cum să extrageți un set de date de la KP.

Ce este un cursor?

Cursorul nu poate fi folosit în MySQL în sine. Este o componentă importantă a procedurilor stocate. Aș compara cursorul cu un "pointer" în C / C ++ sau un iterator în instrucțiunea foreach PHP.







Cu ajutorul cursorului, putem trece prin setul de date și putem procesa fiecare înregistrare în funcție de anumite sarcini.

O astfel de operațiune de prelucrare de înregistrare poate fi efectuată și în nivel PHP, ceea ce reduce considerabil volumul datelor transmise pe nivel de date PHP, așa cum ne putem întoarce pur și simplu sinteza / rezultatul statistic tratate înapoi (eliminând prin prelucrarea select - partea clientului foreach) .

Deoarece cursorul este implementat într-o procedură stocată, are toate avantajele (și dezavantajele) inerente HP (controlul accesului, precompilarea, dificultate de depanare etc.)

Un exemplu de aplicare practică

Pe site-ul meu personal există o pagină cu rezultatele jocurilor echipei mele preferate din NBA: Lakers.

Structura tabelului acestei pagini este destul de simplă:

Cursoare în procedurile memorate mysql, mysql

Figura 1. Structura tabelului rezultatelor jocurilor Lakers

Cursoare în procedurile memorate mysql, mysql

(Folosesc MySQL Workbench ca instrument GUI pentru gestionarea bazei de date MySQL.) Puteți utiliza un alt instrument la alegere.)

Aceasta, desigur, nu este o sarcină imposibilă, dar dacă condițiile devin mai complicate și tabelul de date este mult mai mare, atunci va dura mai mult și probabilitatea de eroare crește.

Putem face acest lucru prin PHP? Da, desigur. Putem obține date despre jocuri (în special, coloana winlos) din acest sezon și să sortăm prin intermediul înregistrărilor pentru a calcula durata seriei actuale de victorii / pierderi într-un rând.

Dar pentru a face acest lucru, va trebui să acopere toate datele pentru anul respectiv, și cele mai multe dintre datele vor fi inutile pentru noi (nu prea probabil ca unele echipa va avea o serie de mai mult de 20+ jocuri la rând în sezonul regulat, care este format din 82 de meciuri ).

Cu toate acestea, nu știm cu siguranță câte înregistrări ar trebui extrase în PHP pentru a defini seria. Deci nu putem face fără să pierdem date inutile. Și, în sfârșit, dacă numărul actual de câștiguri / înfrângeri dintr-un rând este singurul lucru pe care dorim să-l învățăm din acest tabel, atunci de ce vom recupera apoi toate rândurile de date?

Putem să o facem într-un alt mod? Da, este posibil. De exemplu, putem crea o tabelă de rezervă creată special pentru a stoca valoarea curentă a numărului de victorii / pierderi într-un rând.

Adăugarea fiecărei noi înregistrări va actualiza automat și acest tabel. Dar acest lucru este prea greoi și plin de erori.

Cum poți să o faci mai bine?

Utilizarea cursorului într-o procedură memorată

După cum ați putea ghici din titlul acestui articol, cea mai bună alternativă (în opinia mea) de a rezolva această problemă este să folosiți cursorul într-o procedură stocată.

Să creăm primul HP în MySQL Workbench:

În acest HP avem un parametru de intrare și doi parametri de ieșire. Aceasta determină semnătura HP.







În corpul HP, am declarat și câteva variabile locale pentru o serie de rezultate (câștiguri sau pierderi, current_win), seria curentă și starea actuală a câștigării / pierderea unui anumit meci:

Deși acest lucru nu poate fi văzut în mod clar, ne putem imagina că acest set de date va conține o secvență de valori "L" și "W". Pe baza datelor prezentate în figura 2, ar trebui să fie după cum urmează: "LLLLLLLWLL. "(6 valori ale" L ", 1" W "etc.)

Pentru a calcula numărul de victorii / pierderi într-un rând, începem cu ultima (și prima din setul de date dat) care se potrivește. Când cursorul este deschis, acesta începe întotdeauna cu prima intrare din setul de date corespunzător.

După încărcarea primelor date, cursorul se mută la următoarea înregistrare. Astfel, comportamentul cursorului este similar cu coada care se repetă prin sistemul FIFO (First In First Out). Acesta este exact ceea ce avem nevoie.

După obținerea stării actuale a victoriei / înfrângerii și a numărului de elemente identice consecutive din set, vom continua să procesăm restul setului de date pe ciclu. În fiecare iterație a buclă, cursorul va "sări" la următoarea înregistrare, până când vom rupe buclele sau până când toate intrările vor fi traversate.

În cazul în care starea intrării următoare este același ca setul actual de victorii / pierderi consecutive, ceea ce înseamnă că seria va continua, atunci incrementat numărul de victorii consecutive (sau leziuni) de 1, și să continue pentru a sorta date.

Dacă starea este diferită, înseamnă că seria este întreruptă și putem opri ciclul. În cele din urmă, închidem cursorul și lăsăm datele originale. După aceasta, rezultatul este afișat.

Mai mult, putem crește controlul accesului pentru HP, așa cum este descris în articolul meu anterior.

Pentru a testa munca acestui HP, putem scrie un script PHP scurt:

Rezultatul ar trebui să pară așa:

Cursoare în procedurile memorate mysql, mysql

Efectuarea unui set de date dintr-o procedură stocată

De câteva ori în cursul acestui articol, conversația vizează modul de obținere a unui set de date de la HP, care constituie un set de date din rezultatele procesării mai multor convorbiri consecutive către un alt CP.

Utilizatorul poate dori să obțină mai multe informații cu ajutorul HP creat anterior, decât pur și simplu o serie continuă de victorii / pierderi pentru anul; de exemplu, putem crea un tabel în care să fie afișate o serie de victorii / înfrângeri pentru diferiți ani:

(În principiu, mai multe informații vor fi durata cea mai lunga serie de victorii sau înfrângeri într-un anumit sezon. Pentru a rezolva această problemă, puteți extinde cu ușurință descris HP, așa că voi părăsi această sarcină pentru acei cititori care ar fi interesați. În cadrul prezentului articol, vom continua procesarea curent serie de victorii / înfrângeri).

Proceduri memorate MySQL poate returna numai valori scalare (întreg, șir, etc.), spre deosebire de instrucțiunile selectate. din. (rezultatele sunt convertite într-un set de date). Problema este că tabelul în care vrem să obținem rezultate nu există în structura bazei de date existente, ci este compusă din rezultatele prelucrării procedurii stocate.

Pentru a rezolva această problemă, avem nevoie de o masă temporară sau, dacă este posibil și de necesară, de o tabelă de rezervă. Să vedem cum putem rezolva o sarcină existentă folosind o masă temporară.

Mai întâi vom crea un al doilea KP, al cărui cod este prezentat mai jos:

Câteva remarci semnificative la codul de mai sus:

  1. Definim primii și ultimii ani pentru eșantionare din tabelul lakers;
  2. Creăm o tabelă temporară pentru stocarea datelor cu structura necesară (sezon, streak, câștig);
  3. În bucla, vom efectua mai întâi un PC creat anterior cu parametrii necesari (apel cu baleiaj (cur_year, @l, @s);), apoi apuca datele returnate și introduceți-le într-un tabel temporar (a se insera în valori yearly_streak (cur_year, @l, @s) ;);
  4. În cele din urmă, vom selecta din tabelul temporar și vom returna setul de date, după care vom efectua o anumită ajustare (DROP TEMPORARY TABLE IF EXISTS yearly_streak;).

Pentru a obține rezultate, vom crea un alt script PHP, al cărui cod este prezentat mai jos:

Rezultatele afișate pe ecran vor arăta astfel:

Cursoare în procedurile memorate mysql, mysql

Rețineți că metoda de mai sus este ușor diferită de cea a primului nostru HP.

Primul KP nu returnează un set de date - doar doi parametri. În acest caz, folosim PDO exec. și apoi interogare pentru a ieși datele; în cel de-al doilea CP, trimitem un set de date prin acesta, deci folosim interogarea PDO direct prin apelul din CP.

Voila! Am făcut-o!

concluzie

Pe site-ul MySQL puteți găsi documentația oficială privind sintaxa procedurii memorate și diferiți operatori. Puteți vedea materialele despre crearea unei proceduri stocate în acest document. și mai multe informații pentru o înțelegere mai profundă a acestui subiect pot fi găsite aici.

Traducerea articolului "Cursori în procedurile memorate MySQL" a fost pregătită de echipa prietenoasă a proiectului Saitostroenie de la A la Z.







Articole similare

Trimiteți-le prietenilor: