Noņemt no ms sql kursora. Kursori MySQL saglabātajās procedūrās. A. Izmantojot vienkāršu kursoru un sintaksi

Ir dota kursora definīcija. Tiek sniegts tā veidu un uzvedības apraksts: statiskie, dinamiskie, secīgie un taustiņu kursori. Ir aprakstīti kursora vadības principi: kursora izveide un atvēršana, datu nolasīšana, kursora aizvēršana. Ir doti kursora programmēšanas piemēri.

Kursora koncepcija

Pieprasīt uz relāciju datu bāze dati parasti atgriež vairākas datu rindas (ierakstus), bet lietojumprogramma vienlaikus apstrādā tikai vienu ierakstu. Pat tad, ja vienlaikus tiek apstrādātas vairākas rindas (piemēram, datu attēlošana izklājlapu veidā), to skaits joprojām ir ierobežots. Turklāt, pārveidojot, dzēšot vai pievienojot datus, darba vienība ir sērija. Šajā situācijā kursora jēdziens izvirzās priekšplānā, un šajā kontekstā kursors ir rādītājs uz rindu.

Kursors SQL ir apgabals datu bāzes atmiņā, kas paredzēts pēdējā SQL priekšraksta glabāšanai. Ja pašreizējais priekšraksts ir datu bāzes vaicājums, atmiņā tiek saglabāta arī vaicājuma datu rinda, ko sauc par pašreizējo vērtību vai pašreizējo kursora rindiņu. Norādītais apgabals atmiņā ir nosaukts un ir pieejams lietojumprogrammām.

Parasti kursori tiek izmantoti, lai no datu bāzes atlasītu tajā saglabātās informācijas apakškopu. Lietojumprogramma jebkurā laikā var pārbaudīt vienu kursora rindiņu. Kursori bieži tiek izmantoti SQL priekšrakstos, kas iegulti lietojumprogrammās, kas rakstītas procesuālajās valodās. Dažus no tiem netieši izveido datu bāzes serveris, bet citus definē programmētāji.

Saskaņā ar SQL standartu, strādājot ar kursoriem, var izdalīt šādas galvenās darbības:

  • radīšana vai kursora deklarācija;
  • atvēršanas kursors, t.i. aizpildot to ar datiem, kas tiek glabāti daudzlīmeņu atmiņā;
  • atnest no kursora un mainot datu rindas ar to;
  • aizverot kursoru, pēc kura tas kļūst nepieejams lietotāju programmām;
  • kursora atbrīvošana, t.i. kursora kā objekta dzēšana, jo tā aizvēršana ne vienmēr atbrīvo ar to saistīto atmiņu.

Kursora definīcija dažādās implementācijās var nedaudz atšķirties. Piemēram, dažreiz izstrādātājam ir skaidri jāatbrīvo kursoram atvēlētā atmiņa. Pēc atlaidiet kursoru ar to saistītā atmiņa arī tiek atbrīvota. Tas ļauj atkārtoti izmantot viņa vārdu. Citās realizācijās, kad aizverot kursoru atmiņas atbrīvošana notiek netieši. Tūlīt pēc atveseļošanās tas kļūst pieejams citām operācijām: atverot citu kursoru utt.

Dažos gadījumos kursora izmantošana ir neizbēgama. Tomēr, ja iespējams, no tā vajadzētu izvairīties un strādāt ar standarta datu apstrādes komandām: SELECT, UPDATE, INSERT, DELETE. Papildus tam, ka kursori neļauj veikt modifikācijas operācijas uz visu datu apjomu, datu apstrādes operāciju veikšanas ātrums, izmantojot kursoru, ir ievērojami mazāks nekā standarta līdzekļi SQL.

Kursoru ieviešana MS SQL Server vidē

SQL serveris atbalsta trīs veidu kursorus:

  • SQL kursori galvenokārt tiek izmantoti trigeros, saglabātajās procedūrās un skriptos;
  • servera kursori darbojas uz servera un ievieš lietojumprogrammu programmēšanas saskarni ODBC, OLE DB, DB_Library;
  • Klienta kursori tiek ieviesti uz paša klienta. Viņi ienes visu rezultātu rindu kopu no servera un saglabā to lokāli, kas paātrina datu apstrādi, samazinot izšķērdēto laiku, kas pavadīts tīkla darbībām.

Dažādu veidu vairāku lietotāju lietojumprogrammām ir nepieciešama dažāda veida paralēla piekļuve datiem. Dažām lietojumprogrammām nepieciešama tūlītēja piekļuve informācijai par izmaiņām datubāzē. Tas ir raksturīgi biļešu rezervēšanas sistēmām. Citos gadījumos, piemēram, statistikas ziņošanas sistēmās, datu stabilitāte ir svarīga, jo, ja tie tiek pastāvīgi pārveidoti, programmas nevarēs efektīvi attēlot informāciju. Dažādām lietojumprogrammām ir nepieciešamas dažādas kursoru ieviešanas.

Programmā SQL Server kursoru veidi atšķiras atkarībā no to nodrošinātajām iespējām. Kursora veids tiek noteikts tā izveides stadijā, un to nevar mainīt. Daži kursoru veidi var noteikt citu lietotāju veiktās izmaiņas rezultātu kopā iekļautajās rindās. Tomēr SQL Server tikai izseko izmaiņas šādās rindās, kamēr rindai tiek piekļūts, un neļauj mainīt izmaiņas, kad rinda jau ir nolasīta.

Kursori ir sadalīti divās kategorijās: secīgi un ritināms. Pēc kārtasļauj atlasīt datus tikai vienā virzienā – no sākuma līdz beigām. Ritināmi kursori nodrošināt lielāku darbības brīvību - ir iespējams pārvietoties abos virzienos un pāriet uz patvaļīgu kursora rezultātu kopas rindu Ja programma spēj modificēt datus, uz kuriem norāda kursors, to sauc par ritināmu un modificējamu. Runājot par kursoriem, nevajadzētu aizmirst par darījumu izolāciju. Kad viens lietotājs modificē ierakstu, cits to nolasa, izmantojot savu kursoru, un turklāt viņš var modificēt to pašu ierakstu, kas rada nepieciešamību saglabāt datu integritāti.

SQL Server atbalsta statisku, dinamisku, secīgi un to kontrolē atslēgu komplekts.

Shēmā ar statiskais kursors informācija tiek nolasīta no datu bāzes vienreiz un saglabāta kā momentuzņēmums (noteiktā brīdī), tāpēc cita lietotāja veiktās izmaiņas datu bāzē nav redzamas. Kādu brīdi atverot kursoru serveris bloķē visas rindas, kas iekļautas tā pilnajā rezultātu kopā. Statiskais kursors nemainās pēc izveides un vienmēr parāda datu kopu, kas pastāvēja tās atvēršanas brīdī.

Ja citi lietotāji mainīs kursorā iekļautos datus avota tabulā, tas neietekmēs statiskais kursors.

IN statiskais kursors Nav iespējams veikt izmaiņas, tāpēc tas vienmēr tiek atvērts tikai lasīšanas režīmā.

Dinamiskais kursors uztur datus “dzīvā” stāvoklī, taču tam ir nepieciešami tīkla un programmatūras resursi. Izmantojot dinamiskie kursori netiek izveidota pilnīga avota datu kopija, bet dinamiska atlase no avota tabulām tiek veikta tikai tad, kad lietotājs piekļūst noteiktiem datiem. Ieneses laikā serveris bloķē rindas, un visas izmaiņas, ko lietotājs veic pilnā kursora rezultātu kopā, būs redzamas kursorā. Tomēr, ja cits lietotājs ir veicis izmaiņas pēc tam, kad kursors ir ieguvis datus, tās netiks atspoguļotas kursorā.

Kursoru kontrolē taustiņu komplekts, atrodas pa vidu starp šīm galējībām. Ieraksti tiek identificēti izlases laikā, un tādējādi izmaiņas tiek izsekotas. Šis kursora veids ir noderīgs, ieviešot ritināšanu atpakaļ – tad rindu pievienošana un dzēšana nav redzama, kamēr informācija nav atjaunināta un draiveris nav izvēlējies jauna versija ierakstus, ja tajos ir veiktas izmaiņas.

Secīgi kursori neļauj izgūt datus pretējā virzienā. Lietotājs var atlasīt tikai rindas no kursora sākuma līdz beigām. Sērijas kursors nesaglabā visu rindu kopu. Tie tiek nolasīti no datu bāzes, tiklīdz tie ir atlasīti kursorā, kas ļauj dinamiski atspoguļot visas lietotāju veiktās izmaiņas datu bāzē, izmantojot komandas INSERT, UPDATE, DELETE. Kursors parāda jaunāko datu stāvokli.

Statiskie kursori nodrošināt stabilu datu skatījumu. Tie ir piemēroti informācijas "noliktavu" sistēmām: lietojumprogrammām ziņošanas sistēmām vai statistikas un analītiskiem nolūkiem. Turklāt, statiskais kursors labāk nekā citi tiek galā ar liela datu apjoma iztveršanu. Turpretim elektroniskās pirkšanas vai biļešu rezervēšanas sistēmām nepieciešama dinamiska atjauninātās informācijas uztvere, kad tiek veiktas izmaiņas. Šādos gadījumos to izmanto dinamiskais kursors. Šajās lietojumprogrammās pārsūtīto datu apjoms parasti ir neliels, un tiem var piekļūt rindas (atsevišķa ieraksta) līmenī. Grupas piekļuve ir ļoti reta.

Kursora vadība MS SQL Server vidē

Kursora vadība tiek ieviests, izpildot šādas komandas:

  • DEKLARĒT - radīšana vai kursora deklarācija;
  • ATVĒRTS – atvēršanas kursors, t.i. aizpildot to ar datiem;
  • IEŅEMT atnest no kursora un mainot datu rindas, izmantojot kursoru;
  • AIZVĒRT - aizverot kursoru;
  • ATDALĪT — kursora atbrīvošana, t.i. kursora kā objekta dzēšana.

Kursora deklarācija

SQL standarts nodrošina šādu komandu, lai izveidotu kursoru:

Izmantojot atslēgvārdu INSENSITIVE, tiks izveidots statiskais kursors. Datu izmaiņas nav atļauti, turklāt netiek rādītas citu lietotāju veiktās izmaiņas. Ja trūkst atslēgvārda INSENSITIVE, a dinamiskais kursors.

Norādot atslēgvārdu SCROLL, izveidoto kursoru var ritināt jebkurā virzienā, ļaujot izmantot jebkuras atlases komandas. Ja šis arguments tiek izlaists, kursors būs konsekventi, t.i. tā apskate būs iespējama tikai vienā virzienā – no sākuma līdz beigām.

SELECT priekšraksts norāda SELECT pieprasījuma pamattekstu, kas nosaka iegūto rindu kopu kursoram.

Norādot FOR READ_ONLY, tiek izveidots tikai lasāms kursors un netiek atļautas nekādas izmaiņas datos. Tas atšķiras no statiskā, lai gan pēdējais arī neļauj mainīt datus. Var deklarēt kā tikai lasāmu kursoru dinamiskais kursors, kas ļaus parādīt cita lietotāja veiktās izmaiņas.

Kursora izveide ar argumentu FOR UPDATE ļauj izpildīt kursorā datu maiņa vai nu norādītajās kolonnās, vai, ja nav argumenta OF kolonnas_nosaukums, visās kolonnās.

MS SQL Server vidē kursora izveides komandai tiek pieņemta šāda sintakse:

<создание_курсора>::= DEKLARĒT kursora_nosaukumu CURSOR FOR SELECT_paziņojums ]]

Izmantojot atslēgvārdu LOCAL, tiks izveidots lokālais kursors, kas ir redzams tikai pakotnes, aktivizētāja, saglabātās procedūras vai pielāgota funkcija. Kad pakotne, aktivizētājs, procedūra vai funkcija tiek pārtraukta, kursors tiek netieši iznīcināts. Lai nodotu kursora saturu ārpus konstrukcijas, kas to izveidoja, tā parametram ir jāpiešķir arguments OUTPUT.

Ja ir norādīts GLOBAL atslēgvārds, tiek izveidots globālais kursors; tas pastāv, līdz pašreizējais savienojums tiek aizvērts.

Norādot FORWARD_ONLY izveido sērijas kursors; Datus var atlasīt tikai virzienā no pirmās rindas līdz pēdējai.

Norādot SCROLL, tiek izveidots ritināms kursors; Datiem var piekļūt jebkurā secībā un jebkurā virzienā.

Norādot STATIC, tiek izveidots statiskais kursors.

Norādot KEYSET, tiek izveidots taustiņa kursors.

Norādot DYNAMIC, tiek izveidots dinamiskais kursors.

Ja norādāt argumentu FAST_FORWARD kursoram READ_ONLY, izveidotais kursors tiks optimizēts ātra piekļuve uz datiem. Šo argumentu nevar izmantot kopā ar argumentiem FORWARD_ONLY un OPTIMISTIC.

Kursors, kas izveidots ar OPTIMISTIC argumentu, neļauj mainīt vai dzēst rindas, kas tika modificētas pēc kursora atvēršana.

Norādot argumentu TYPE_WARNING, serveris informēs lietotāju par netiešām kursora veida izmaiņām, ja tas nav saderīgs ar SELECT vaicājumu.

Kursora atvēršana

Priekš atverot kursoru un aizpildot to ar datiem no SELECT vaicājuma, kas norādīts, veidojot kursoru, izmantojiet šādu komandu:

Pēc atverot kursoru Tiek izpildīts saistītais SELECT priekšraksts, kura izvade tiek saglabāta daudzlīmeņu atmiņā.

Datu izgūšana no kursora

Uzreiz pēc atverot kursoru varat atlasīt tā saturu (atbilstošā vaicājuma izpildes rezultātu), izmantojot šādu komandu:

Norādot FIRST, tiks atgriezta kursora pilnās rezultātu kopas pati pirmā rinda, kas kļūst par pašreizējo rindu.

Norādot PĒDĒJĀ, tiek atgriezta pēdējā kursora rinda. Tā arī kļūst par pašreizējo līniju.

Norādot NEXT, tiek atgriezta rinda uzreiz pēc pašreizējās pilnā rezultātu kopā. Tagad tas kļūst aktuāls. Pēc noklusējuma komanda FETCH izmanto šo metodi rindu ienešanai.

Atslēgvārds PRIOR atgriež rindu pirms pašreizējās. Tas kļūst aktuāls.

Arguments ABSOLUTE (rindas_numurs | @line_number_mainīgs) atgriež rindu pēc tās absolūtā kārtas numura kursora pilnajā rezultātu kopā. Rindas numuru var norādīt, izmantojot konstanti vai kā mainīgā lieluma nosaukumu, kurā tiek saglabāts rindas numurs. Mainīgajam ir jābūt vesela skaitļa datu tipam. Ir norādītas gan pozitīvas, gan negatīvas vērtības. Norādot pozitīvu vērtību, virkne tiek skaitīta no kopas sākuma, bet negatīvā vērtība tiek skaitīta no beigām. Atlasītā rinda kļūst par pašreizējo līniju. Ja ir norādīta nulles vērtība, neviena rinda netiek atgriezta.

Arguments RELATIVE (rindu skaits | @mainīgs rindu skaits) atgriež rindu, kas ir norādītais rindu skaits pēc pašreizējās. Ja norādāt negatīvu rindu skaitu, tiks atgriezta rinda, kas ir norādītais rindu skaits pirms pašreizējās. Norādot nulles vērtību, tiks atgriezta pašreizējā rinda. Atgrieztā rinda kļūst par pašreizējo rindu.

Uz atvērt globālo kursoru, pirms tā nosaukuma ir jānorāda GLOBAL atslēgvārds. Kursora nosaukumu var norādīt arī, izmantojot mainīgo.

Dizainā INTO @mainīgā_nosaukums [,...n] ir norādīts mainīgo lielumu saraksts, kurā tiks saglabātas atgrieztās rindas atbilstošās kolonnu vērtības. Mainīgo norādīšanas secībai ir jāatbilst kursora kolonnu secībai, un mainīgā datu tipam ir jāatbilst datu veidam kursora kolonnā. Ja INTO konstrukcija nav norādīta, tad komandas FETCH darbība līdzinās komandas SELECT uzvedībai - dati tiek parādīti ekrānā.

Datu maiņa un dzēšana

Lai veiktu izmaiņas, izmantojot kursoru, jums ir jāizdod komanda UPDATE šādā formātā:

Ar vienu darbību var mainīt vairākas pašreizējās kursora rindas kolonnas, taču tām visām ir jāatrodas vienā tabulā.

Lai dzēstu datus, izmantojot kursoru, izmantojiet komandu DELETE šādā formātā:

Rezultātā līnijas iestatītā strāva kursorā tiks dzēsta.

Kursora aizvēršana

Pēc aizvēršanas kursors programmas lietotājiem kļūst nepieejams. Kad tas ir aizvērts, visas tās darbības laikā uzstādītās slēdzenes tiek noņemtas. Slēgšanu var piemērot tikai atvērtiem kursoriem. Slēgts, bet ne atbrīvots kursors var tikt atvērts atkārtoti. Nav atļauts aizvērt neatvērtu kursoru.

Atlaidiet kursoru

Kursora aizvēršana ne vienmēr atbrīvo ar to saistīto atmiņu. Dažām implementācijām tas ir skaidri jāatbrīvo, izmantojot priekšrakstu DEALLOCATE. Pēc atlaidiet kursoru Tiek atbrīvota arī atmiņa, kas ļauj atkārtoti izmantot kursora nosaukumu.

Lai kontrolētu, vai ir sasniegts kursora beigas, ieteicams izmantot funkciju: @@FETCH_STATUS

Funkcija @@FETCH_STATUS atgriež:

0, ja ielāde bija veiksmīga;

1, ja ielāde neizdevās, jo tika mēģināts ienest līniju ārpus kursora;

2, ja ielāde neizdevās, jo mēģināts piekļūt dzēstai vai pārveidotai rindai.

DEKLARĒT @id_kl INT, @firm VARCHAR(50), @fam VARCHAR(50), @message VARCHAR(80), @nam VARCHAR(50), @d DATETIME, @p INT, @s INT SET @s=0 PRINT "Iepirkumu saraksts" DEKLARĀT klient_cursor CURSOR LOCAL FOR SELECT Klienta kods, uzņēmums, uzvārds FROM Client WHERE City="Maskava" PASŪTĪJUMS PĒC Uzņēmuma, uzvārds OPEN klient_cursor IEŅEMT TĀLĀK NO klient_kursora UZ @id_kl, @firm, @fam CH_STATUS@FEM =0 BEGIN SELECT @message="Klients "+@fam+ "Uzņēmums "+ @firm PRINT @message SELECT @message="Produkta nosaukums Pirkuma datums Maksa" DRUKĀT @ziņojums DEKLARĀT tovar_cursor KURSORS ATLASĪTIES Produktam.Nosaukums, darījums.Datums, produkts .Cena* Darījums. Daudzums KĀ izmaksas NO produkta IEKŠĒJS PIEVIENOJIES Darījums PAR produktu. Produkta kods=Transaction.Product Code WHERE Transaction.Customer Code=@id_kl OPEN tovar_cursor FETCH NEXT FROM FROM tovar_cursor INTO @nam, @d, @p IF @@FETCH_STATUS<>0 DRUKĀT "Nav pirkumu", KAmēr @@FETCH_STATUS=0 SĀKT ATLASĪT @ziņa=" "+@nam+" "+ CAST(@d AS CHAR(12))+" "+ CAST(@p AS CHAR(6)) DRUKĀT @message SET @s=@s+@p IEŅEMT TĀLĀK NO tovar_cursor UZ @nam, @d, @p BEIGAS AIZVĒRT tovar_cursor ATTEIKT tovar_cursor SELECT @message="Kopējās izmaksas "+ CAST(@s AS CHAR(6)) PRINT @message -- pāriet uz nākamo klientu -- IEŅEMT TĀLĀK NO klient_cursor UZ @id_kl, @firm, @fam END AIZVĒRT klient_cursor ATTEIKT klient_kursoru Piemērs 13.6. Kursors, lai parādītu Maskavas klientu iegādāto preču sarakstu un to kopējās izmaksas.

Piemērs 13.7. Izstrādājiet ritināmu kursoru klientiem no Maskavas. Ja tālruņa numurs sākas ar 1, izdzēsiet klientu ar šo numuru un pirmajā kursora ierakstā aizstājiet tālruņa numura pirmo ciparu ar 4.

DEKLARĀT @firma VARCHAR(50), @fam VARCHAR(50), @tel VARCHAR(8), @ziņa VARCHAR(80) DRUKĀT "Klientu sarakstu" DEKLARĒT klient_cursor KURSORA GLOBĀLĀ RITINĀŠANAS KEYSET IZVĒLĒTIES Firmai, Uzvārds, Tālrunis FROM Client KUR Pilsēta ="Maskava" PASŪTĪJUMS PĒC uzņēmuma, Uzvārds ATJAUNINĀŠANAI ATVĒRT klient_cursor IEŅEMT TĀLĀK NO klient_kursors UZ @firm, @fam, @tel WHILE @@FETCH_STATUS=0 SĀKT ATLASĪT @message="Klients "+@fam+ " Uzņēmums "+ @firm " Phone "+ @tel PRINT @message -- ja tālruņa numurs sākas ar 1, -- izdzēsiet klientu ar šo numuru IF @tel LIKE '1%' DELETE Client WHERE CURRENT OF klient_cursor ELSE -- pāriet uz nākamo klients IEŅEMT TĀLĀK NO klient_kursora UZ @firm, @fam, @tel BEIGĀS IEŅEMT ABSOLŪTI 1 NO klient_cursor UZ @firm, @fam, @tel -- pirmajā ierakstā tālruņa numura pirmo ciparu nomainiet ar 4 UPDATE Client SET Phone ='4' + LABAIS(@ tel,LEN(@tel)-1)) KUR PAŠREIZĒJĀS klient_kursors IZVĒLĒTIES @ziņa="Klients "+@fam+" Firma "+ @firma "Tālrunis"+ @tel DRUKĀT @ziņa AIZVĒRT klient_kursoru ATTIECĪT klienta_kursoru Piemērs 13.7. Ritināms kursors klientiem no Maskavas.

Piemērs 13.8. Lietošana kursors kā procedūras izejas parametrs. Procedūra atgriež datu kopu - produktu sarakstu.

Procedūras izsaukšana un datu drukāšana no izvades kursora tiek veikta šādi:

DECLARE @my_cur CURSOR DECLARE @n VARCHAR(20) EXEC my_proc @cur=@my_cur IZRĀDE IEŅEMT TĀLĀK NO @my_cur INTO @n SELECT @n WHILE (@@FETCH_STATUS=0) SĀKT IEŅEMT TĀLĀK NO @my_cur @n BEIGAS AIZVĒRT @my_cur ATDALĪT @my_cur


Kursors ir saite uz kontekstuālās atmiņas apgabalu. Dažās SQL programmēšanas valodas (Oracle, Microsoft SQL Serveris) - rezultātu kopa, kas iegūta, izpildot vaicājumu, un ar to saistītais pašreizējā ieraksta rādītājs. Es teiktu, ka kursors ir virtuālais galds kas ir alternatīva datu krātuve. Šajā gadījumā kursors ļauj piekļūt tā datiem tā, it kā tie būtu parasta masīva dati.
Kursori tiek izmantoti saglabātajās procedūrās. Pietiekami daudz teorijas, apskatīsim piemēru:
Mums ir datu bāze (datubāze ir nedaudz slikta, tā ir viena no manām laboratorijas darbi, bet mūsu datu bāzes skolotājs uzstāja uz šādu struktūru)
/*bankas informācija*/
IZVEIDOT TABULU "banka" (

`BankName` VARCHAR (50) COLLATE utf8_bin NOT NULL NOKLUSĒJUMS "" ,


PRIMĀRĀ ATSLĒGA ("Bankas ID")

)ENGINE=InnoDB
Rakstzīmju kopa "utf8" SĀKOT "utf8_bin" ;
/*dati par noguldījumiem */
IZVEIDOT TABULU "bankas izplatīšana" (
`BankId' INTEGER (11) NOT NULL ,
"Persent" INTEGER (11) NOKLUSĒJUMS NULL ,
ContributeAmount DECIMAL (10,0) NOT NULL ,
"ClientId" INTEGER (11) NOT NULL ,
PRIMARY KEY ("Bankas ID", "ClientId"),
KEY `BankId` (`BankId`),
KEY `ClientId` (`ClientId`),
IEROBEŽOJUMI `bankdistribution_fk` ĀRĒJĀ ATSLĒGA (`BankId`) ATSAUCES `bank` (`BankId`),
IEROBEŽOJUMS `bankdistribution_fk1` ĀRĒJĀ ATSLĒGA (`ClientId`) ATSAUCES `klients` (`ClientId`)
)ENGINE=InnoDB
/*dati par investoriem*/
IZVEIDOT TABULU "klients" (
"ClientId" INTEGER (3) NOT NULL AUTO_INCREMENT,
`CreditCardId` BIGINT(10) NOT NULL ,
`Uzvārds` VARCHAR (50) COLATE utf8_bin NOT NULL DEFAULT "" ,
`Nosaukums` VARCHAR (50) COLLATE utf8_bin NOT NULL NOKLUSĒJUMS "" ,
`FirstName` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,
Tālrunis VARCHAR (50) COLLATE utf8_bin NOT NULL NOKLUSĒJUMS "" ,
`Adrese` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,
"SafeId" INTEGER (5) NOT NULL ,
PRIMĀRĀ ATSLĒGA (klienta ID, kredītkartes ID),
KEY `ClientId` (`ClientId`)

)ENGINE=InnoDB
AUTO_INCREMENT=11 CHARACTER SET "utf8" SĀKOT "utf8_bin"

Pieņemsim, ka mums ir jāsaņem katra banka pēc kārtas un jāveic ar to dažas darbības. Tālāk sniegtais vaicājums varētu mums palīdzēt

Atlasiet `banku`.* NO `bankas' IEROBEŽOJUMA NUMURS NO THE_RECORD_WEED,1
. Tādējādi, izmantojot LIMIT WE NEED_RECORD NUMBER, 1, mēs izvelkam katru ierakstu ciklā no bankas tabulas un veicam ar to vajadzīgās darbības, vienlaikus palielinot WE NEED_RECORD NUMBER vērtību par 1. Tagad mēs darīsim to pašu, bet izmantosim kursors
Sāciet
/* mainīgie, kuros mēs izgūstam datus */
Deklarēt vBankId veselu skaitli ;
Izziņot vBankName VARCHAR (50);
Deklarēt vAdresi VARCHAR(50);
Paziņot vPhone VARCHAR (50);
/* hadlera mainīgais — a*/
Pasludināt pabeigtu veselu skaitļu noklusējuma vērtību 0;
/*Kursora deklarācija*/
Declare BankCursor kursors Select `bank`.`BankId`, `bank`.`BankName`, `bank`.`Address`, `bank`.`Tālrunis, NO `bankas` kur 1;
/*APSTRĀDĀTĀJA mērķis, kas tiks paskaidrots tālāk*/
DEKLARĒT TURPINĀTĀJU SQLSTATUSAM "02000" SET done=1;
/* atvērt kursoru */
Atvērt BankCursor;
/*izgūt datus*/
KAmēr darīts = 0 DO

mēs veicam nepieciešamās darbības
BEIGAS ;
/*aizverot kursoru*/
Aizvērt BankCursor;
BEIGAS ;

* Šis avota kods tika izcelts, izmantojot avota koda izcelšanas rīku.

Kļūda: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)

Ziņojums: nav datu — nav ielādēta, atlasīta vai apstrādāta nulle rindu

SQLSTATE: 02000 Aktivizējas, kad ir sasniegts kursora beigas vai kad atlase vai atjaunināšana atgriež tukšu virkni.

Nākamajā rindā mēs deklarējām kursoru DECLARE cursor_name CURSOR FOR select_statement;
Atvērt kursoru Atvērt kursora_nosaukums;
Pēc tam, līdz sasniedzam kursora beigas (WHILE done = 0 DO), mēs iegūstam datus un apstrādājam tos.
Pirms iziet no saglabātās procedūras, kursors ir jāaizver. Aizvērt kursora_nosaukums;

Tas nešķiet sarežģīti. Taču ar SQLSTATE "02000" ir saistītas daudzas nepilnības.

KAmēr darīts = 0 DO
IEŅEMT BankCursor INTO vBankId,vBankName,vAddress,vPhone;

Atlasiet (ContributeAmount) INTO vContributeAmountSUM NO bankdistribution, kur BankId = vBankId limits 1;
mēs veicam dažas darbības
BEIGAS ;

* Šis avota kods tika izcelts, izmantojot avota koda izcelšanas rīku.


Viss ir labi un pareizi no sintakses viedokļa. Bet no loģiskā viedokļa nē. Var gadīties, ka noguldītāji nav atvēruši kontus kādā bankā, tad Select (ContributeAmount) INTO vContributeAmountSUM FROM bankas izplatīšanai kur BankId = vBankId limits 1; SQLSTATE: tiks aktivizēts 02000, pabeigtais mainīgais tiks iestatīts uz 1 un kamēr cilpa beigsies agrāk, nekā gaidījām. No tā var izvairīties, rīkojoties šādi
KAmēr darīts = 0 DO
IEŅEMT BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* izraksts bankai jebkura tās noguldījuma summas */


if (vContributeAmountSUM > 0), tad
/* izraksts bankai jebkura tās noguldījuma summas */

beigas, ja ;
mēs veicam dažas darbības
BEIGAS ;

* Šis avota kods tika izcelts, izmantojot avota koda izcelšanas rīku.


Ar pirmo pieprasījumu mēs pārbaudījām, vai ir iemaksas (ja tādas nav, tad vContributeAmountSUM == 0) un tikai tad, ja tādas ir, mēs izgūstam datus.

Tagad pieņemsim, ka katram klientam ir jānoņem kopējā summa kontos dažādās bankās
Deklarēt ClientSummCursor Kursors for Izvēlieties summu

Deklarēt ClientSummCursor kursoru, lai atlasītu summu (bankdistribution. ContributeAmount), bankdistribution. ClientId NO 'bankdistribution' iekšējā savienojuma klienta vietā (client.ClientId = bankdistribution.`ClientId`), kur 1 grupē pēc `bankdistribution. `ClientId';

Atvērt ClientSummCursor;
KAmēr darīts = 0 DO
IEŅEMT BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* izraksts bankai jebkura tās noguldījuma summas */
Atlasiet Count(ContributeAmount) INTO vContributeAmountSUM NO bankdistribution, kur BankId = vBankId limits 1;
/* pārbaudiet, vai šajā bankā tiešām ir noguldījumi */
if (vContributeAmountSUM > 0), tad
/* izraksts bankai jebkura tās noguldījuma summas */
Atlasiet ContributeAmount INTO vContributeAmountSUM NO bankdistribution, kur BankId = vBankId limits 1;
beigas, ja ;


mēs veicam dažas darbības.
BEIGAS ;

* Šis avota kods tika izcelts, izmantojot avota koda izcelšanas rīku.

Tāda pati situācija var rasties, ja dati ClientSummCursor kursorā beidzas agrāk nekā dati BankCursor, tiek aktivizēts SQLSTATE: 02000, pabeigtais mainīgais ir iestatīts uz 1 un while cilpa beidzas agrāk, nekā mēs gaidījām. No tā var izvairīties, rīkojoties šādi

Atvērt ClientSummCursor;
KAmēr darīts = 0 DO
IEŅEMT BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* izraksts bankai jebkura tās noguldījuma summas */
Atlasiet Count(ContributeAmount) INTO vContributeAmountSUM NO bankdistribution, kur BankId = vBankId limits 1;
/* pārbaudiet, vai šajā bankā tiešām ir noguldījumi */
if (vContributeAmountSUM > 0), tad
/* izraksts bankai jebkura tās noguldījuma summas */
Atlasiet ContributeAmount INTO vContributeAmountSUM NO bankdistribution, kur BankId = vBankId limits 1;
beigas, ja ;
/* pirms datu izvilkšanas no otrā kursora, atcerieties sqlstate stāvokli */
SET old_status = pabeigts;
/* izvelciet mums nepieciešamos datus */
IEŅEMT ClientSummCursor INTO vSum,vClientId;
/* pārbaudiet, vai dati tika izgūti un vai sqlstate 0200 neizdevās */
ja (izdarīts = 0), tad
mēs veicam dažas darbības.
beigas, ja ;
/* pirms brīža beigām atjauno pabeigtā mainīgā vērtību */
iestatīts darīts = vecais_statuss;
BEIGAS ;

* Šis avota kods tika izcelts, izmantojot avota koda izcelšanas rīku.

Paldies visiem, kas līdz šim ir lasījuši, ceru, ka kādam noderēs.

TAS ATTIECAS UZ: SQL Server (kopš 2008)Base SQL dati Azure SQL Data WarehouseParallel Data Warehouse

Definē Transact-SQL servera kursora atribūtus, piemēram, skata rekvizītus un vaicājumu, ko izmanto, lai izveidotu rezultātu kopu, uz kuras darbojas kursors. Paziņojums DECLARE CURSOR atbalsta gan ISO standarta sintaksi, gan sintaksi, kas izmanto Transact-SQL valodas paplašinājumu kopu.

ISO sintakse DEKLARĒT kursora_nosaukumu [ NEJŪTĪGS ] [ RITINĀT ] KURSORS Select_statement [ FOR ( TIKAI LASĪT | ATJAUNINĀJUMS [ OF kolonnas_nosaukums [ ,...n ] ] ) ] [;] Transact-SQL paplašinātā sintakse DEKLARĒT kursora_nosaukums KURSORS [ LOCAL | GLOBĀLS ] [ FORWARD_ONLY | RITINĀT ] [ STATISKA | KEYSET | DINAMISKAIS | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTISKA ] [ TIPA_BRĪDINĀJUMS ] FOR select_statement [ ATJAUNINĀŠANAI [ OF kolonnas_nosaukums [ ,...n ] ] ] [;]

kursora_nosaukums
kursora_nosaukums

NEJŪTĪGS
tempdb; tādējādi izmaiņas pamatā esošajās tabulās netiek atspoguļotas datos, ko atgriež šī kursora atlase, un šis kursors nav maināms. Izmantojot ISO sintaksi, ja vien nav norādīta opcija NEJŪTĪGA, pamata tabulās veiktie atjauninājumi un dzējumi tiek parādīti turpmākajās atlasēs.

RITINĀT
Norāda, ka ir pieejamas visas izlases iespējas (PIRMAIS, PĒDĒJAIS, PRIOR, NEXT, RELATIVE, ABSOLUTE). Ja priekšrakstā ISO DECLARE CURSOR nav norādīta opcija SCROLL, tiek atbalstīta tikai opcija NEXT fetch. Opciju SCROLL nevar norādīt ar opciju FAST_FORWARD.

atlasīt_paziņojumu
Standarta SELECT paziņojums, kas nosaka kursora rezultātu kopu. Atslēgvārdi FOR BROWSE un INTO nav atļauti atlasīt_paziņojumu kursora deklarācija.

atlasīt_paziņojumu konflikts ar pieprasītā veida kursoru.

TIKAI LASĪT

Atjaunināt ]
kolonnas_nosaukums [, .. .n] ir norādīts, izmaiņas pieļauj tikai uzskaitītajās kolonnās. Ja UPDATE priekšraksts tiek izmantots bez kolonnu saraksta, tad atjauninājums ir iespējams visām kolonnām.

kursora_nosaukums
Konkrētā servera kursora Transact-SQL nosaukums. kursora_nosaukums jāievēro identifikatoru noteikumi.

VIETĒJS
Norāda, ka kursors ir lokāls pakotnei, saglabātajai procedūrai vai aktivizētājam, kurā tas tika izveidots. Kursora nosaukums ir derīgs tikai šajā apgabalā. Uz kursoru var atsaukties, izmantojot pakotnes lokālos mainīgos, saglabātās procedūras, trigerus vai saglabātās procedūras izvades parametru. Parametrs OUTPUT tiek izmantots, lai nodotu lokālo kursoru izsaucējai pakotnei, saglabātajai procedūrai vai aktivizētājam, kas pēc tam var piešķirt parametru kursora mainīgajam, lai pēc tam, kad saglabātā procedūra ir pabeigta, piekļūtu kursoram. Kursors tiek netieši atbrīvots, kad partija, saglabātā procedūra vai trigeris pabeidz izpildi, ja vien kursors nav nodots parametram OUTPUT. Ja kursors tika nodots parametram OUTPUT, kursors tiek atbrīvots, kad tiek atbrīvoti visi mainīgie, kas atsaucas uz to, vai kad tiek iziets no tvēruma.

GLOBĀLI
Norāda, ka savienojumam kursors ir globāls. Kursora nosaukumu var izmantot jebkura saglabātā procedūra vai pakotne, kas darbojas savienojumā. Kursors tiek netieši atbrīvots tikai tad, ja savienojums ir bojāts.

FORWARD_ONLY
Norāda, ka kursoru var skatīt tikai no pirmās rindas līdz pēdējai. Tiek atbalstīta tikai ieneses opcija FETCH NEXT. Ja FORWARD_ONLY ir norādīts bez atslēgvārdiem STATIC, KEYSET vai DYNAMIC, kursors darbojas kā DINAMISKAIS kursors. Ja nav norādīts ne arguments FORWARD_ONLY, ne arguments SCROLL, pēc noklusējuma ir arguments FORWARD_ONLY, ja vien nav atslēgvārdu STATIC, KEYSET vai DYNAMIC. Kursoriem STATIC, KEYSET un DYNAMIC ir noklusējuma vērtība SCROLL. Atšķirībā no datu bāzes API, piemēram, ODBC un ADO, režīmu FORWARD_ONLY atbalsta šādi Transact-SQL kursori: STATIC, KEYSET un DYNAMIC.

STATISKA
Definē kursoru, kas izveido pagaidu datu kopiju, ko izmantot kursors. Visi kursora vaicājumi piekļūst norādītajai pagaidu tabulai tempdb; tādējādi izmaiņas pamatā esošajās tabulās netiek atspoguļotas datos, ko atgriež šī kursora atlase, un šis kursors nav maināms.

KEYSET
Norāda, ka kursora rindu dalība vai secība paliek nemainīga, kad tas tiek atvērts. Tabulā ir iebūvēts atslēgu komplekts, kas unikāli identificē rindas tempdb sauca atslēgas.

Kursora īpašnieka veiktās vai citu lietotāju veiktās bezatslēgas vērtību izmaiņas pamata tabulās tiek parādītas, kad kursora īpašnieks to apskata. Citu lietotāju veiktās izmaiņas netiek atspoguļotas (izmaiņas nevar veikt, izmantojot Transact-SQL servera kursoru). Ja rinda tiek dzēsta, mēģinot ienest rindas, tiek atgriezta @@FETCH_STATUS -2. Galveno vērtību atjauninājumi kursora robežu dēļ ir līdzīgi vecas rindas dzēšanai un pēc tam ievietošanai jauna līnija. Rinda ar jaunajām vērtībām nav redzama, un mēģinājumi ienest rindu ar vecajām vērtībām atgriež @@FETCH_STATUS -2. Atjauninājumi ir redzami nekavējoties, ja tie tiek veikti, izmantojot kursoru, izmantojot klauzulu WHERE CURRENT OF.

DINAMIKA
Definē kursoru, kas parāda visas datu izmaiņas, kas veiktas rezultātu kopas rindās, skatot šo kursoru. Datu vērtības, secība un rindas piederība katrā atlasē var atšķirties. Atlases opciju ABSOLUTE neatbalsta dinamiskie kursori.

ĀTRI UZ PRIEKŠU
Norāda FORWARD_ONLY, READ_ONLY kursoru, kuram ir iespējota veiktspējas optimizācija. Opciju FAST_FORWARD nevar norādīt ar opcijām SCROLL vai FOR_UPDATE.

TIKAI LASĪT
Novērš izmaiņas, kas veiktas, izmantojot šo kursoru. Klauzula WHERE CURRENT OF nevar atsaukties uz kursoru priekšrakstā UPDATE vai DELETE. Šai opcijai ir prioritāte pār noklusējuma kursora atsvaidzināšanas līdzekli.

SCROLL_LOCKS
Norāda, ka pozicionētie atjauninājumi vai dzējumi, kas veikti, izmantojot kursoru, ir garantēti veiksmīgi. SQL Server bloķē rindas, kad tās tiek nolasītas kursorā, lai nodrošinātu, ka šīs rindas ir pieejamas turpmākajām izmaiņām. Opciju SCROLL_LOCKS nevar norādīt ar opciju FAST_FORWARD vai STATIC.

OPTIMISTISKA
Norāda, ka pozicionētie atjauninājumi vai dzēšana, kas veikta, izmantojot kursoru, neizdosies, ja rinda ir atjaunināta kopš tās nolasīšanas kursorā. SQL Server nebloķē rindas, kad tās tiek nolasītas kursorā. Tā vietā tiek izmantoti salīdzinājumi laika zīmogs kolonnu vērtības vai kontrolsummas, ja tabulā nav laika zīmogs kolonnu, lai noteiktu, vai rinda ir mainījusies kopš tās nolasīšanas kursorā. Ja rinda ir mainīta, pozicionētās atjaunināšanas vai dzēšanas mēģinājumi neizdosies. Opciju OPTIMISTIC nevar norādīt ar opciju FAST_FORWARD.

TYPE_WARNING
Norāda, ka klientam tiks nosūtīts brīdinājums, ja kursors tiek netieši pārveidots no viena pieprasītā veida uz citu.

atlasīt_paziņojumu
Standarta SELECT priekšraksts, kas norāda kursora rezultātu kopu. Atslēgvārdi COMPUTE, COMPUTE BY, FOR BROWSE un INTO nav atļauti atlasīt_paziņojumu kursora deklarācija.

SQL Server netieši pārvērš kursoru uz citu tipu, ja klauzulas ir iekļautas atlasīt_paziņojumu konflikts ar pieprasītā veida kursoru. Papildinformāciju skatiet sadaļā Netiešā kursora reklāmguvumi.

ATJAUNINĀŠANAI]
Definē atjaunināmās kursora kolonnas. Ja OF kolonnas_nosaukums [, ... n] ir nodrošināts, izmaiņas ir atļautas tikai uzskaitītajās kolonnās. Ja UPDATE priekšraksts tiek izmantots bez kolonnu saraksta, tad atjauninājums ir iespējams visām kolonnām, ja vien nav norādīta vienlaicības opcija READ_ONLY.

Paziņojums DECLARE CURSOR definē Transact-SQL servera kursora atribūtus, piemēram, skata rekvizītus un vaicājumu, ko izmanto, lai izveidotu rezultātu kopu, kurā darbojas kursors. Priekšraksts OPEN aizpilda rezultātu kopu, un FETCH priekšraksts atgriež no tās rindu. Paziņojums CLOSE notīra pašreizējo rezultātu kopu, kas saistīta ar kursoru. Paziņojums DEALLOCATE atbrīvo kursora izmantotos resursus.

Pirmā priekšraksta DECLARE CURSOR forma izmanto ISO sintaksi, lai norādītu kursora parametrus. Otrajā priekšraksta DECLARE CURSOR formā tiek izmantoti Transact-SQL valodas paplašinājumi, kas ļauj definēt kursorus, izmantojot tos pašus veidus, kas tiek izmantoti datu bāzes API kursora funkcijās, piemēram, ODBC un ADO.

Šīs divas formas nevar sajaukt. Ja pirms atslēgvārda CURSOR norādāt SCROLL vai izlaižat atslēgvārdus, jūs nevarat izmantot atslēgvārdus starp CURSOR un arī atlasīt_paziņojumu atslēgvārdi. Norādot atslēgvārdus starp KURSORU, kā arī priekš atlasīt_paziņojumu atslēgvārdus, jūs nevarat norādīt SCROLL vai INSENSITIVE pirms CURSOR atslēgvārda.

Ja priekšrakstam DECLARE CURSOR izmantojat Transact-SQL sintaksi un nenorāda opcijas READ_ONLY, OPTIMISTIC vai SCROLL_LOCKS, tiek pieņemta šāda noklusējuma vērtība.

    Ja SELECT priekšraksts neatbalsta atjauninājumus (vai tam nav pietiekamas atļaujas, vai tiek piekļūts attālām tabulām, kas neatbalsta atjauninājumus utt.), kursors ir iestatīts uz READ_ONLY.

    STATIC un FAST_FORWARD kursori pēc noklusējuma ir READ_ONLY.

    DYNAMIC un KEYSET kursori pēc noklusējuma ir OPTIMISTIC.

Uz kursoriem var atsaukties tikai citi Transact-SQL priekšraksti. Datu bāzes API funkcijas nevar atsaukties uz kursoriem. Piemēram, kad kursors ir deklarēts, OLE DB, ODBC vai ADO funkcijas un metodes nevar atsaukties uz tā nosaukumu. Kursora rindas nevar atlasīt, izmantojot atbilstošās API funkcijas un metodes; Šim nolūkam ir jāizmanto Transact-SQL FETCH priekšraksti.

Tālāk norādītās saglabātās procedūras var izmantot, lai definētu kursora īpašības pēc tā deklarēšanas.

Mainīgos var izmantot kā daļu atlasīt_paziņojumu, kurā ir deklarēts kursors. Kursora mainīgo vērtības pēc tā deklarēšanas nemainās.

Pēc noklusējuma DECLARE CURSOR atļaujas tiek piešķirtas visiem lietotājiem, kuriem ir SELECT atļauja kursora izmantotajos skatos, tabulās un kolonnās.

Tabulā ar kopu kolonnu krātuves indeksu nevar izmantot kursorus vai aktivizētājus. Šis ierobežojums neattiecas uz negrupētiem indeksiem; Varat izmantot kursorus un aktivizētājus tabulā ar negrupētu kolonnu krātuves indeksu.

A. Izmantojot vienkāršu kursoru un sintaksi

Rezultātu kopa, kas izveidota, atverot šo kursoru, ietver visas tabulas rindas un kolonnas. Šo kursoru var atjaunināt, visi atjauninājumi un dzējumi ir attēloti šī kursora atlasē. FETCH``NEXT ir ienest tikai tāpēc, ka netika norādīts parametrs SCROLL.

DECLARE vend_cursor CURSOR FOR SELECT * FROM Purchasing.Vendor OPEN vend_cursor FETCH NEXT FROM vend_cursor;

B. Ligzdoto kursoru izmantošana, lai parādītu atskaiti

Nākamajā piemērā tiek izmantoti ligzdoti kursori, lai parādītu sarežģītu pārskatu. Katram pakalpojumu sniedzējam tiek deklarēts iekšējais kursors.

IESTATĪT NOCOUNT ON ; DECLARE @vendor_id int, @vendor_name nvarchar (50), @message varchar (80), @product nvarchar (50); DRUKĀT" -------- Pārdevēja produktu pārskats --------"; DECLARE vendor_cursor CURSOR FOR SELECT VendorID, Name FROM Purchasing.Vendor WHERE PreferredVendorStatus = 1 ORDER BY VendorID; OPEN vendor_cursor IEŅEMT TĀLĀK NO vendor_cursor UZ @vendor_id, @vendor_name WHILE @@FETCH_STATUS = 0 SĀKT DRUKĀT " " ATLASĪT @ziņojums = "----- Produkti no pārdevēja: "+ @vendor_name PRINT @ message -- Pasludināt, pamatojoties uz iekšējo kursoru -- uz vendor_id no ārējā kursora. DEKLARĒT product_cursor CURSOR FOR SELECT v.Name FROM Purchasing.ProductVendor pv, Production.Product v WHERE pv.ProductID = v.ProductID UN pv.VendorID = @vendor_id -- Ārējā kursora mainīgā vērtība ATVĒRT produkta_kursoru IEŅEMT TĀLĀK NO produkta_kursora UZ @product IF @@FETCH_STATUS<>0 PRINT "<>" WHILE @@FETCH_STATUS = 0 BEGIN SELECT @message = " " + @product DRUKĀT @ziņojums IEŅEMT TĀLĀK NO product_cursor UZ @product END CLOSE product_cursor ATTIECINĀT product_cursor — iegūstiet nākamo piegādātāju. IEŅEMT TĀLĀK NO vendor_cursor UZ @vendor_name, @vendor_id END CLOSE vendor_cursor; ATJAUNĀT vendor_cursor;

Var gadīties, ka atbilde uz vienkāršu klienta pieprasījumu būs simtiem tūkstošu rindu paraugs, kas lielākajai daļai klientu ir nesagremojams. Šajā gadījumā mijiedarbības ar klientiem problēmas risinājums ir izmantot kursorus kā universālu mehānismu datu apmaiņai starp serveri un klientu. Kursori darbojas ar rezultātu datu kopu (vaicājuma rezultātu), sniedzot lietotājiem papildu datu apstrādes iespējas:

Kursori ļauj strādāt ar tabulas rindām, norādot to sērijas numuru datu kopā;

Kursori ļauj īstenot sarežģītas datu modifikācijas darbības, piemēram, ja, mainot kolonnas vērtību, ir nepieciešams atkārtoti piekļūt citu kolonnu vērtībām.

Kursora dzīves cikls:

Kursora izveide: DEKLARĒT<имя курсора>[ NEJŪTĪGS ] [ RITINĀT ] KURSORS UZ< SELECT -оператор>PAREDZĒT (TIKAI LASĪT | ATJAUNINĀT)

Šeit atslēgvārds INSENSITIVE nozīmē, ka kursors būs statisks (datu momentuzņēmums), savukārt pēc noklusējuma kursors tiek izveidots dinamisks (ienese tiek veikta katru reizi, kad tiek atvērta rinda). Atslēgvārds SCROLL nozīmē, ka kursoru var ritināt jebkurā virzienā, pretējā gadījumā kursors tiek izveidots kā "secīgs" kursors.

Atvēršanas kursors: ATVĒRTS [GLOBĀLS]<имя курсора>. Kursors, kas norādīts kā GLOBAL, netiek automātiski izdzēsts, kad beidzas procedūra vai pakotne, no kuras tas tika izsaukts.

Lasīšanadatus : IEŅEMT [[ TĀLĀK | PRIOR | PIRMAIS | PĒDĒJĀ | ABSOLUTE n | RELATĪVAIS n ] NO ] [ GLOBĀLS ]<имя курсора>[INTO@mainīgā_nosaukums,...]. SQL Server 2000 ļauj no kursora nolasīt tikai vienu rindu. PIRMAIS atslēgvārds ir atgriezt kursora pirmo rindu; LAST – kursora pēdējā rinda; NEXT – nākamā rinda pēc pašreizējās, atgrieztā rinda kļūst par pašreizējo; PRIOR – iepriekšējais pirms pašreizējā; ABSOLUTE n – atgriež rindu pēc tās absolūtā kārtas numura kursorā; RELATĪVS – n rindas aiz pašreizējās. Kolonnas dati tiks saglabāti katrā no norādītajiem mainīgajiem tādā secībā, kādā tie ir uzskaitīti.

Mainīt datus: izpilda komandu UPDATE ar sintaksi, kas paredzēta darbam ar kursoriem.

Dzēst datus: izpilda komandu DELETE ar sintaksi, kas paredzēta darbam ar kursoriem.

Kursora aizvēršana: AIZVĒRT [GLOBĀLI]<имя курсора>

Atlaidiet kursoru: ATDALĪT [GLOBĀLI]<имя курсора>

Kursora izmantošanas piemērs:

DECLARE fo_curs CURSOR STATIC FOR

SELECT name_rus no ORDER BY name_rus

DEKLARĒT @name varchar(50)

IEŅEMT PIRMAIS NO fo_curs INTO @name

WHILE @@FETCH_STATUS=0

IEŅEMT TĀLĀK NO fo_curs INTO @name

ATJAUNĀT fo_curs

2.7. Datu drošības un integritātes nodrošināšana Microsoft SQL Server. Datu bāzes pārvaldība. Lomas. Tiesību piešķiršana lietotājiem (GRANT, DENY, REVOKE). Datu aizsardzības metodes un tehnoloģijas SQL Server.

SQL Server drošība un administrēšana. .

DBVS galvenais uzdevums ir nodrošināt datu integritāti un konsekvenci izvēlētajā priekšmetu jomā. Viens no faktoriem, kas neļauj sistēmai atrisināties šo uzdevumu, ir lietotāju darbības, kas nejauši vai tīši mēģina iznīcināt datu struktūru vai mainīt pašus datus. Līdz ar to DBVS ir jāaizsargā ne tikai no fiziskām kļūmēm, bet arī no lietotājiem, kuri nav piemēroti realizējamo uzdevumu veikšanai. Lai to izdarītu, ir jāizstrādā un jāpievieno datu bāzei drošības sistēma, kas neļaus lietotājiem veikt darbības ārpus viņu pilnvarām.

Datu bāzes pārvaldība

Lai izveidotu datu bāzi, izmantojot TSQL, izmantojiet komandu CREATE DATABASE, taču parasti šim nolūkam tiek izmantotas SQL Server Management Studio iespējas. IN SQL serveris tiek definētas diezgan daudzas datu bāzes operācijas: failu izmēru palielināšana (samazināšanās), konfigurācijas maiņa (komanda ALTER), pievienošana un atdalīšana, īpašumtiesību nodošana, nosaukuma maiņa, rekvizītu apskate un, visbeidzot, dzēšana (DROP DATABASE).

Tāpat kā lielākajai daļai datu bāzes serveru, arī SQL Server ir lietotājs ar pilnām administratīvām tiesībām – tas ir Sistēmas administrators vai "sa". Pēc sākotnējās servera instalēšanas sa parole ir tukša. Lietotājs, kurš izveido jaunu datu bāzi, automātiski kļūst par tās īpašnieku ("dbo" — datu bāzes īpašnieks) datu bāzes izveides laikā tiek definēts arī lietotājs "viesis". konkrētu datu bāzi, lietotājam tiek piešķirta netieša piekļuve ar Viesa vārda izmantošana viesis parasti ir aizliegta.

Lietotājs, kurš izveido objektu datu bāzē, automātiski kļūst par tā īpašnieku, un neviens, ieskaitot dbo un sa, nevar izmantot šo objektu, kamēr īpašnieks nav piešķir tam tiesības. Bet, lai lietotājs varētu izveidot objektu, datu bāzes īpašniekam vispirms ir jāpiešķir viņam atbilstošās tiesības.

Loma ļauj apvienot lietotājus, kas veic vienas un tās pašas funkcijas, lai vienkāršotu administrēšanu. Lomas var būt iebūvētas vai pielāgotas. Iebūvētās lomas tiek īstenotas servera līmenī un datu bāzes līmenī. Tālāk ir parādīta iebūvēto datu bāzes lomu tabula:

db_īpašnieks. Ir visas tiesības uz datu bāzi

db_accessadmin. Var pievienot vai noņemt lietotājus

Db_securityadmin. Pārvalda visas atļaujas, objektus, lomas un lietotājus

Db_ddladmin. Var izpildīt visas DDL komandas, izņemot GRANT, DENY, REVOKE

Db_backupoperator. Arhivārs var izpildīt komandas. datus

db_datareader. Varbūt skatīšanās. jebkuri dati jebkurā tabulā

db_datawriter. Varbūt modifikācija. jebkuri dati jebkurā tabulā

Db_denydatareader. Aizliegts skats mīlestība dati jebkurā tabulas

Db_denydatawriter. Aizliegt mainīt jebkādus datus jebkurā tabulā

Tiesību piešķiršana lietotājiem. SQL Server drošības pamats ir (1) Konti(konti); (2) lietotāji; (3) lomas; (4) grupas.

Kad lietotājs izveido savienojumu ar SQL Server, darbības, ko viņš var veikt, nosaka viņam kā lietotājam un lomas dalībniekam piešķirtās tiesības. Tiesības piešķir DBVS administrators, datu bāzes īpašnieks vai konkrēta datu bāzes objekta īpašnieks. Tiesības uz datu bāzi var iedalīt trīs kategorijās: (1) tiesības piekļūt datu bāzes objektiem; (2) tiesības izpildīt TSQL komandas; (3) netiešās tiesības. Serveris ļauj nodot īpašumtiesības no viena lietotāja citam.

Lai pārvaldītu lietotāja atļaujas piekļūt datu bāzes objektiem, tiek izmantotas šādas komandas:

GRANT(VISI |< вид действия >,…}

( IESL. (<имя таблицы или представления>} [(<имя столбца>,…)]

| ON(< имя хранимой процедуры >}

| ON(< имя пользовательской функции >}

UZ ( PUBLISKS |<имя объекта системы безопасности>,…}

[AS<имя группы> | <имя роли>]

tiesību piešķiršana lietotājiem, Kur

ALL – lietotājam tiek piešķirtas visas iespējamās atļaujas, pretējā gadījumā norādiet

<вид действия>– tiesības uz lietotājam pieejamām darbībām, proti:

SELECT – skatam, tabulas kolonnai un tabulai (skats)

INSERT – pievienot, tabulai (skatam) kopumā

UPDATE – izmaiņām, tabulas kolonnai un tabulai (skats)

DELETE – dzēst, tabulai (skatam) kopumā

EXECUTE – lai izpildītu saglabātās procedūras

ATSAUKSMES – iespēja atsaukties uz noteiktu objektu (iekļaut to kā daļu no ārējās atslēgas).

<имя объекта системы безопасности>– SQL Server konti, Windows domēna lietotāji; PUBLISKS — visiem lietotājiem.

AR PIEŠĶIRŠANAS IESPĒJU - ļauj lietotājam, kuram šobrīd ir piešķirtas tiesības, piešķirt piekļuves tiesības objektam citiem lietotājiem.

AS<имя группы> | <имя роли>– lietotāja dalība lomā, kurai ir dota iespēja piešķirt tiesības citiem lietotājiem.

ATTIECĪBĀ UZ autoriem ATLASĪT publiski

PIEŠĶIRT, ATJAUNINĀT, IZDZĒST autoriem Mariju, Džonu, Tomu

GRANT SELECT ON Plan_Data UZ Grāmatvedību AR GRANT OPCIJU

GRANT SELECT ON Plan_Data TO Jack AS grāmatvedība

Džeks nav grāmatvedības lomas dalībnieks, taču kāds šajā lomā var piešķirt atļauju

NOLIEGT(VISI |< вид действия >,…}

( IESL. (<имя таблицы или представления>} [(<имя столбца>,…)]

| ON(<имя хранимой процедуры>}

| ON(<имя пользовательской функции>}

UZ ( PUBLISKS |<имя объекта системы безопасности>,…}

piekļuves aizliegums lietotājiem datu bāzes objektiem. KASKĀDE atņem tiesības ne tikai no dotajam lietotājam, bet arī visiem, kam viņš piešķīris tiesības.

Piemērs (ieslēgts pavēles aizliegums TSQL):

AIZLIEGT TABULU VEIDOT Džeka KASKĀDEI

Komanda ATCELT izmanto, lai netieši liegtu piekļuvi datu bāzes objektiem. Sintakse ir tāda pati kā komandai DENY. Netiešais liegums ir līdzīgs piekļuves liegšanai, izņemot to, ka tas attiecas tikai tajā līmenī, kurā tas ir definēts. Piemērs: lietotājam Džekam, kurš ir GoodUsers lomas dalībnieks, tiek piešķirtas piekļuves tiesības tabulai XFiles. Ja ir liegts REVOKE, lai GoodUsers loma varētu piekļūt šai tabulai, Džeks joprojām var piekļūt šai tabulai, jo viņam ir skaidri noteiktas tiesības. Ja jūs personīgi izmantojat REVOKE viņam, viņš zaudēs tiesības piekļūt XFiles.

Lomām piešķirtās atļaujas manto to dalībnieki. Ja lietotājam tiek piešķirta piekļuve objektam, piederot vienai lomai, bet tiek liegta cita loma, piekļuves konflikts vienmēr tiek atrisināts par labu liegumam.

Datu aizsardzības tehnoloģijas MS SQL Server

1.Mehānisms kontrolpunktiem– kontrolpunkti, kas tiek ģenerēti pēc ~60 s, lai ierakstītu diskā atjauninātās lapas (kontrolpunktu var piespiest ar CHECKPOINT komandu).

2. Iebūvētie un ārējie mehānismi datu bāzes integritātes pārbaudei (tiek palaists automātiski vai, tāpat kā DBCC utilīta - Database Consistency Checker - manuāli).

3. Datubāzes failu fiziska dublēšana (ja atļauta), izmantojot operētājsistēmu (ieskaitot spoguļattēlu cieto disku mehānismu).

4. Datu bāzu un darījumu žurnālu dublēšana - ierakstot datu bāzes izgāztuves dublēšanas ierīcē (magnētiskajā lentē vai cietajā diskā).

5. Replikācija – iespēja dublēt informāciju, periodiski (dažos gadījumos sinhroni) pārsūtot to no viena SQL servera uz otru.

6. Trafika šifrēšana starp klientu un serveri, kā arī kodu šifrēšana, ko izmanto darbam ar datu bāzes objektiem (saglabātās procedūras, trigeri utt.)

1) Kursora jēdziens
Interaktīvā SQL nenošķir vienas rindas vaicājumus no vairāku rindu vaicājumiem. Iegultais SQL šos vaicājumus izpilda atšķirīgi. Vienas rindiņas vaicājumi atgriež vienu rindiņu, un mēs tos jau esam apskatījuši. Ja vaicājuma rezultāts ir vairāk nekā viena rinda, iegultajam SQL ir jāļauj lietojumprogrammai izgūt vaicājuma rezultātus pēc rindas. Šim nolūkam tiek izmantoti kursori. Kursors ir mainīgais, kas saistīts ar vaicājumu. Tās vērtība ir katra rinda, kas atbilst vaicājumam. Tāpat kā mainīgie, arī kursori ir jādeklarē, pirms tos var izmantot. Atšķirībā no skatiem, kursori ir paredzēti apstrādei pa rindiņām.

2) Kursora deklarācija

DEKLARĒT [{}] [[] RITINĀT] KURSORS [{AR|BEZ} TURĒT] PRIEKŠ [PRIEKŠ {TIKAI LASĪT | ATJAUNINĀT [OF ]}]

3) Atslēgvārdi
. JUTĪGS|NEJŪTĪGS|JŪTĪGS– ir redzamas izmaiņas rezultātu kopā | aizliegts (fiksēts, izmantojot datu kopas kopiju)|DBVS pati izlemj, vai izveidot kopiju (darbojas pēc noklusējuma).
. AR|BEZ Aizturēšanas– lapas vaļā | aizver kursoru, ja tiek konstatēts COMMIT priekšraksts.
. RITINĀT– [novērš] rezultātu rindu izvilkšanu nejaušā secībā.
. TIKAI LASĪŠANAI– definē tikai lasāmu kursoru.
. ATJAUNINĀŠANAI– bloķē tikai norādīto kolonnu atjaunināšanu.

4) Kursora deklarēšana SQL serverī

DEKLARĒT KURSORS [LOKĀLS|GLOBĀLS] [FORWARD_ONLY|RITNIET] [STATIC|KEYSET|DINAMIC|FAST_FORWARD] [READ_ONLY|SCROLL_LOCKS|OPTIMISTISKI] PRIEKŠ [ATJAUNINĀŠANAI [OF ]]

. STATISKA– definē kursoru, kas izveido pagaidu datu kopiju, ko izmantot kursors. Visi vaicājumi pret kursoru piekļūst norādītajai pagaidu tabulai tempdb datu bāzē, tāpēc izmaiņas bāzes tabulās neietekmē datus, kas tiek atgriezti paraugiem šim kursoram, un pats kursors neļauj veikt izmaiņas.
. KEYSET– Norāda, ka kursora dalība vai rindu secība pēc tā atvēršanas nemainās. Atslēgu kopa, kas unikāli identificē rindas, ir iebūvēta tempdb datu bāzes tabulā, ko sauc par atslēgu kopu.
. DINAMIKA– Definē kursoru, kas parāda visas datu izmaiņas, kas veiktas rezultātu kopas rindās, skatot šo kursoru. Datu vērtības, secība un dalība rindās katrā atlasē var atšķirties. Atlases opciju ABSOLUTE neatbalsta dinamiskie kursori.
. ĀTRI UZ PRIEKŠU– Norāda FORWARD_ONLY, READ_ONLY kursoru, kuram ir iespējota veiktspējas optimizācija. Opciju FAST_FORWARD nevar norādīt ar opcijām SCROLL vai FOR_UPDATE.
. SCROLL_LOCKS– Norāda, ka pozicionētie atjauninājumi vai dzēšana, izmantojot kursoru, ir garantēta veiksmīga. SQL Server bloķē rindas, kad tās tiek nolasītas kursorā, lai nodrošinātu, ka tās ir pieejamas turpmākām izmaiņām. Opciju SCROLL_LOCKS nevar norādīt ar opciju FAST_FORWARD vai STATIC.
. OPTIMISTISKA– Norāda, ka pozicionētie atjauninājumi vai dzēšana, izmantojot kursoru, neizdosies, ja rinda ir atjaunināta kopš brīža, kad tā tika nolasīta kursorā. SQL Server nebloķē rindas, kad tās tiek nolasītas kursorā. Tā vietā tiek salīdzinātas laikspiedola kolonnas vērtības (vai kontrolsummas, ja tabulā nav laikspiedola kolonnas), lai noteiktu, vai rinda ir mainījusies kopš tās nolasīšanas kursorā. Ja rinda ir modificēta, tās pozicionētā modifikācija vai dzēšana nav iespējama. Opciju OPTIMISTIC nevar norādīt ar opciju FAST_FORWARD.

5) Kursora atvēršana

6) Rindu izgūšana no kursora

IEŅEMT [{NĀKAMAIS|PRIOR|PIRMAIS|PĒDĒJAIS|{ABSOLŪTS|RELATĪVS }}]
NO INTO

7) Kursora pozicionēšanas iespējas
. NĀKAMAIS|PRIOR|PIRMAIS|PĒDĒJAIS– uz rezultātu kopas nākamo|iepriekšējo|pirmo|pēdējo rindiņu.
. RELATĪVAIS ±N– uz līniju ar pozitīvu vai negatīvu nobīdi attiecībā pret pašreizējo līniju.
. ABSOLŪTS ±N– uz rindu ar skaidri norādītu absolūtās pozīcijas numuru no kursora sākuma vai beigām.

Piezīme: SQL Server ļauj izmantot veselu skaitļu mainīgo @N, nevis N.

8) Kursora aizvēršana

9) Piezīmes par kursoriem
. Ja kursors satur vairāk nekā vienu rindiņu, ir jāorganizē cilpa datu izgūšanai no tā, periodiski pārbaudot, lai sasniegtu pēdējo rindiņu.
. Atšķirībā no tabulām un skatiem, kursora rindas tiek sakārtotas vai nu tieši, izmantojot sadaļu SAKĀRTOT PĒC, vai saskaņā ar konvencijām, kas pieņemtas konkrētā DBVS.
. Kursori tiek izmantoti arī, lai atlasītu rindu grupas no tabulām, kuras var atjaunināt vai dzēst pa vienai.
. Lai kursoru varētu atjaunināt, tam jāatbilst tiem pašiem kritērijiem kā skatam, tas ir, tajā nedrīkst būt sadaļas UNION, ORDER BY, GROUP BY, DISTINCT.

10) Piemērs datu dzēšanai no kursora

exec sql deklarēt kursoru Cur1, lai atlasītu * no klienta
kur Vērtējums
// drukāt (@f1+’ ‘+convert(Varchar(5),@f2))
exec sql dzēst no klienta
kur Cur1 strāva; ) – paņemiet datus, lai dzēstu no kursora
nav izdarīts:
exec sql aizvērt kursoru Cur1; — Aizveriet kursoru
Izeja();

11) Piemērs komisijas maksas palielināšanai

exec sql deklarēt kursoru CurCust atlasei * no SalesPeople
kur SNum in (atlasiet SNum no Klienta, kur Vērtējums = 300); — definējiet kursoru
exec sql atvērt kursoru CurCust; - Izpildiet kursoru
while (sqlca.sqlcode==0) (— Izveidojiet cilpu, lai atjauninātu datus tabulā
exec sql ielādē CurCust into:Id_num, :SalesPerson, :Loc, :Comm;
exec sql update SalesPeople iestata Comm=Comm+.01 kur pašreizējais
no CurCust; ) – paņemiet no kursora datus atjaunināšanai
exec sql aizvērt kursoru CurCust; — Aizveriet kursoru

SELECT S.Name, MAX(S.City) AS Pilsēta, SUM(O.Amt) AS Amt FROM SalesPeople S INNER JOIN Pasūtījumi O ON S.SNum=O.SNum GROUP BY S. Name PASŪTĪT PĒC 2

DEKLARĒT Cur1 RITINĀŠANAS KURSORU ATLASĪTIES S.Vārds, MAX(S.City) AS Pilsēta, SUM(O.Amt) AS Amt NO Pārdevēji S IEKŠĒJĀ PIEVIENOTIES Pasūtījumi O ON S.SNum=O.SNum GRUPA PĒC S.Vārds PASŪTĪJUMS PĒC 2
OPEN Cur1
IEŅEMT TĀLĀK NO Cur1
WHILE @@FETCH_STATUS=0
SĀKT
IEŅEMT TĀLĀK NO Cur1
BEIGAS
AIZVĒRT Cur1
ATZĪT Cur1