Uklanjanje iz ms sql kursora. Kursori u MySQL pohranjenim procedurama. A. Korišćenje jednostavnog kursora i sintakse

Definicija kursora je data. Dat je opis njegovih tipova i ponašanja: statički, dinamički, sekvencijalni i ključni kursori. Opisani su principi kontrole kursora: kreiranje i otvaranje kursora, čitanje podataka, zatvaranje kursora. Dati su primjeri programiranja kursora.

Koncept kursora

Upit prema relacijskoj bazi podataka obično vraća više redova (zapisa) podataka, ali aplikacija obrađuje samo jedan po jedan zapis. Čak i ako se istovremeno bavi nekoliko redova (na primjer, prikazom podataka u obliku proračunskih tablica), njihov broj je i dalje ograničen. Osim toga, kada mijenjate, brišete ili dodajete podatke, radna jedinica je serija. U ovoj situaciji, koncept kursora dolazi do izražaja, au tom kontekstu kursor je pokazivač na red.

Kursor u SQL-u je područje u memoriji baze podataka koje je dizajnirano da drži posljednju SQL naredbu. Ako je trenutni izraz upit baze podataka, red podataka upita koji se zove trenutna vrijednost, ili trenutna linija kursora, također se pohranjuje u memoriju. Navedeno područje u memoriji je imenovano i dostupno aplikacijskim programima.

Tipično, kursori se koriste za odabir iz baze podataka podskupa informacija pohranjenih u njoj. Aplikacijski program može u svakom trenutku provjeriti jednu liniju kursora. Kursori se često koriste u SQL izrazima ugrađenim u aplikativne programe napisane proceduralnim jezicima. Neke od njih implicitno kreira server baze podataka, dok druge definišu programeri.

U skladu sa SQL standardom, pri radu sa kursorima mogu se razlikovati sljedeće glavne radnje:

  • stvaranje ili deklaracija kursora;
  • kursor za otvaranje, tj. popunjavanje podacima koji su pohranjeni u memoriji na više nivoa;
  • izbor iz kursora i mijenjanje redova podataka s njim;
  • zatvaranje kursora, nakon čega postaje nedostupan korisničkim programima;
  • oslobađanje kursora, tj. brisanje kursora kao objekta jer njegovo zatvaranje ne oslobađa nužno memoriju koja je s njim povezana.

Definicija kursora može se neznatno razlikovati od implementacije. Na primjer, ponekad programer mora eksplicitno osloboditi memoriju dodijeljenu za kursor. Poslije pustite kursor njegova pridružena memorija se također oslobađa. Ovo omogućava ponovnu upotrebu njegovog imena. U drugim implementacijama kada zatvaranje kursora oslobađanje memorije se dešava implicitno. Odmah nakon oporavka postaje dostupan za druge operacije: otvaranje drugog kursora itd.

U nekim slučajevima korištenje kursora je neizbježno. Međutim, ako je moguće, ovo treba izbjegavati i raditi sa standardnim naredbama za obradu podataka: SELECT, UPDATE, INSERT, DELETE. Pored činjenice da kursori ne dozvoljavaju operacije modifikacije na cijelom volumenu podataka, brzina izvođenja operacija obrade podataka pomoću kursora je znatno niža od brzine standardnim sredstvima SQL.

Implementacija kursora u MS SQL Server okruženju

SQL Server podržava tri vrste kursora:

  • SQL kursori se prvenstveno koriste unutar okidača, pohranjenih procedura i skripti;
  • serverski kursori rade na serveru i implementiraju sučelje za programiranje aplikacije za ODBC, OLE DB, DB_Library;
  • Klijentski kursori su implementirani na samom klijentu. Oni preuzimaju cijeli skup redova rezultata sa servera i pohranjuju ga lokalno, što ubrzava obradu podataka smanjujući izgubljeno vrijeme provedeno na mrežnim operacijama.

Različiti tipovi višekorisničkih aplikacija zahtijevaju različite vrste paralelnog pristupa podacima. Neke aplikacije zahtijevaju trenutni pristup informacijama o promjenama u bazi podataka. Ovo je tipično za sisteme za rezervaciju karata. U drugim slučajevima, kao što su statistički sistemi izvještavanja, stabilnost podataka je važna jer ako se stalno mijenjaju, programi neće moći efikasno prikazati informacije. Različite aplikacije trebaju različite implementacije kursora.

U SQL Serveru, tipovi kursora se razlikuju po mogućnostima koje pružaju. Tip kursora se određuje u fazi njegovog kreiranja i ne može se mijenjati. Neki tipovi kursora mogu otkriti promjene koje su drugi korisnici napravili u redovima uključenim u skup rezultata. Međutim, SQL Server samo prati promjene u takvim redovima dok se red pristupa i ne dozvoljava izmjenu promjena nakon što je red već pročitan.

Kursori su podijeljeni u dvije kategorije: sekvencijalno i scrollable. Konsekutivno omogućavaju vam da odaberete podatke samo u jednom smjeru - od početka do kraja. Pokazivači koji se mogu pomicati pružaju veću slobodu djelovanja - moguće je kretati se u oba smjera i skočiti na proizvoljan red skupa rezultata kursora.Ako program može modificirati podatke na koje kursor pokazuje, to se naziva pomicanjem i modifikacijom. Govoreći o kursorima, ne treba zaboraviti na izolaciju transakcija. Kada jedan korisnik izmijeni zapis, drugi ga čita koristeći svoj kursor, a osim toga, može modificirati isti zapis, što čini neophodnim održavanje integriteta podataka.

SQL Server podržava statičke, dinamičke, sekvencijalno i kontrolisano setom ključeva.

U šemi sa statički kursor informacije se čitaju iz baze jednom i pohranjuju kao snimak (od nekog trenutka), tako da promjene koje je u bazi podataka napravio drugi korisnik nisu vidljive. Neko vrijeme otvaranje kursora server postavlja zaključavanje na sve redove uključene u njegov puni skup rezultata. Statički kursor se ne mijenja nakon kreiranja i uvijek prikazuje skup podataka koji je postojao u trenutku njegovog otvaranja.

Ako drugi korisnici promijene podatke uključene u kursor u izvornoj tablici, to neće utjecati na statički kursor.

IN statički kursor Nije moguće izvršiti promjene, tako da se uvijek otvara u načinu samo za čitanje.

Dinamički kursor održava podatke u "živom" stanju, ali to zahtijeva mrežne i softverske resurse. Koristeći dinamički kursori ne kreira se kompletna kopija izvornih podataka, već se dinamički odabir vrši iz izvornih tabela samo kada korisnik pristupi određenim podacima. Tokom dohvaćanja, server zaključava redove i sve promjene koje korisnik napravi u punom skupu rezultata kursora bit će vidljive u kursoru. Međutim, ako je drugi korisnik napravio promjene nakon što je kursor dohvatio podatke, one se neće odraziti u kursoru.

Kursor se kontroliše pomoću seta tastera, nalazi se u sredini između ovih ekstrema. Zapisi se identifikuju u trenutku uzorkovanja i tako se prate promjene. Ovaj tip kursora je koristan kada se implementira pomicanje unazad - tada dodaci i brisanje redova nisu vidljivi dok se informacije ne ažuriraju i upravljački program odabere nova verzija evidencije, ako su u njima izvršene promjene.

Sekvencijalni kursori nije dozvoljeno dohvaćanje podataka u obrnutom smjeru. Korisnik može odabrati samo redove od početka do kraja kursora. Serijski kursor ne pohranjuje skup svih redova. Čitaju se iz baze podataka čim se izaberu u kursoru, što omogućava da se sve promjene koje korisnici izvrše u bazi podataka dinamički reflektiraju pomoću naredbi INSERT, UPDATE, DELETE. Kursor pokazuje najnovije stanje podataka.

Statički kursori pružaju stabilan prikaz podataka. Oni su dobri za sisteme "skladišta" informacija: aplikacije za sisteme izvještavanja ili za statističke i analitičke svrhe. osim toga, statički kursor bolje od drugih podnosi uzorkovanje velikih količina podataka. Suprotno tome, sistemi elektronske kupovine ili rezervacije karata zahtijevaju dinamičku percepciju ažuriranih informacija kako se promjene unose. U takvim slučajevima se koristi dinamički kursor. U ovim aplikacijama, količina prenesenih podataka je obično mala i pristupa se na nivou reda (pojedinačnog zapisa). Grupni pristup je vrlo rijedak.

Upravljanje kursorom u MS SQL Server okruženju

Kontrola kursora implementira se izvršavanjem sljedećih naredbi:

  • DECLARE - stvaranje ili deklaracija kursora;
  • OTVOREN – kursor za otvaranje, tj. popunjavanje podataka;
  • FETCH izbor iz kursora i mijenjanje redova podataka pomoću kursora;
  • ZATVORI - zatvaranje kursora;
  • ODLOČI – oslobađanje kursora, tj. brisanje kursora kao objekta.

Cursor Declaration

SQL standard pruža sljedeću naredbu za kreiranje kursora:

Korištenje ključne riječi INSENSITIVE će stvoriti statički kursor. Promjene podataka nisu dozvoljene, osim toga, promjene koje su napravili drugi korisnici se ne prikazuju. Ako nedostaje ključna riječ INSENSITIVE, a dinamički kursor.

Kada navedete ključnu riječ SCROLL, kreirani kursor se može pomicati u bilo kojem smjeru, što vam omogućava korištenje bilo koje komande za odabir. Ako se ovaj argument izostavi, kursor će biti dosljedan, tj. njegovo gledanje će biti moguće samo u jednom smjeru - od početka do kraja.

SELECT izraz specificira tijelo SELECT zahtjeva, koji određuje rezultujući skup redova za kursor.

Određivanjem FOR READ_ONLY kreira se kursor samo za čitanje i ne dozvoljava se nikakve modifikacije podataka. Razlikuje se od statičkog, iako potonji također ne dozvoljava promjenu podataka. Može se deklarisati kao kursor samo za čitanje dinamički kursor, što će omogućiti prikaz promjena koje je napravio drugi korisnik.

Kreiranje kursora sa argumentom FOR UPDATE omogućava vam da ga izvršite u kursoru promjena podataka bilo u navedenim stupcima ili, u odsustvu argumenta OF column_name, u svim stupcima.

U okruženju MS SQL Servera, sljedeća sintaksa za naredbu za kreiranje kursora je prihvaćena:

<создание_курсора>::= DECLARE cursor_name KURSOR ZA SELECT_naredbu ]]

Upotreba ključne riječi LOCAL stvorit će lokalni kursor koji je vidljiv samo unutar opsega paketa, okidača, pohranjene procedure ili prilagođena funkcija. Kada se paket, okidač, procedura ili funkcija završi, kursor se implicitno uništava. Da biste proslijedili sadržaj kursora izvan konstrukcije koja ga je kreirala, njegovom parametru morate dodijeliti OUTPUT argument.

Ako je navedena ključna riječ GLOBAL, kreira se globalni kursor; postoji sve dok se trenutna veza ne zatvori.

Navođenje FORWARD_ONLY kreira serijski kursor; Podaci se mogu uzorkovati samo u smjeru od prvog do posljednjeg reda.

Navođenje SCROLL kreira kursor koji se može pomerati; Podacima se može pristupiti bilo kojim redoslijedom i u bilo kojem smjeru.

Navođenje STATIC kreira statički kursor.

Navođenjem KEYSET-a kreira se kursor ključa.

Navođenje DYNAMIC kreira dinamički kursor.

Ako navedete argument FAST_FORWARD za READ_ONLY kursor, kreirani kursor će biti optimiziran za brz pristup na podatke. Ovaj argument se ne može koristiti zajedno s argumentima FORWARD_ONLY ili OPTIMISTIC.

Kursor kreiran s argumentom OPTIMISTIC sprječava modifikaciju ili brisanje redova koji su izmijenjeni nakon otvaranje kursora.

Specificiranjem argumenta TYPE_WARNING, poslužitelj će obavijestiti korisnika o implicitnoj promjeni tipa kursora ako je nekompatibilan sa SELECT upitom.

Otvaranje kursora

Za otvaranje kursora i ispunite ga podacima iz SELECT upita navedenog prilikom kreiranja kursora, koristite sljedeću naredbu:

Poslije otvaranje kursora Izvršava se pridruženi SELECT izraz, čiji se izlaz pohranjuje u višerazinskoj memoriji.

Preuzimanje podataka iz kursora

Odmah nakon otvaranje kursora možete odabrati njegov sadržaj (rezultat izvršavanja odgovarajućeg upita) pomoću sljedeće naredbe:

Navođenje FIRST će vratiti prvi red kompletnog skupa rezultata kursora, koji postaje trenutni red.

Određivanjem LAST vraća se najnoviji red kursora. Takođe postaje trenutna linija.

Određivanjem NEXT vraća se red odmah iza trenutnog u punom skupu rezultata. Sada postaje aktuelno. Podrazumevano, naredba FETCH koristi ovu metodu za dohvaćanje redova.

Ključna riječ PRIOR vraća red prije tekućeg. Postaje aktuelno.

Argument APSOLUTNO (broj_line | @promjenjiva_broj_line) vraća red po njegovom apsolutnom rednom broju u kompletnom skupu rezultata kursora. Broj reda se može specificirati pomoću konstante ili kao ime varijable u kojoj je pohranjen broj reda. Varijabla mora biti cjelobrojni tip podataka. Označene su i pozitivne i negativne vrijednosti. Kada se specificira pozitivna vrijednost, niz se broji od početka skupa, dok se negativna vrijednost broji od kraja. Odabrana linija postaje trenutna linija. Ako je navedena nulta vrijednost, ne vraća se nijedan red.

Argument RELATIVNO (broj redova | @promenljivi broj redova) vraća red koji je specificirani broj redova nakon trenutnog. Ako navedete negativan broj redova, bit će vraćen red koji je specificirani broj redova prije trenutnog. Navođenje null vrijednosti će vratiti trenutni red. Vraćeni red postaje trenutni red.

To otvori globalni kursor, morate navesti ključnu riječ GLOBAL prije njenog imena. Ime kursora se također može specificirati pomoću varijable.

U dizajnu INTO @ime_varijable [,...n] navedena je lista varijabli u kojoj će biti pohranjene odgovarajuće vrijednosti stupca vraćenog reda. Redoslijed specificiranja varijabli mora odgovarati redoslijedu stupaca u kursoru, a tip podataka varijable mora odgovarati tipu podataka u stupcu kursora. Ako INTO konstrukcija nije specificirana, tada će ponašanje naredbe FETCH ličiti na ponašanje naredbe SELECT - podaci se prikazuju na ekranu.

Promjena i brisanje podataka

Da izvršite promjene pomoću kursora, morate izdati naredbu UPDATE u sljedećem formatu:

Nekoliko kolona trenutnog reda kursora može se promijeniti u jednoj operaciji, ali svi moraju pripadati istoj tablici.

Za brisanje podataka pomoću kursora koristite naredbu DELETE u sljedećem formatu:

Kao rezultat, trenutna linija postavljena u kursoru će biti izbrisana.

Zatvaranje kursora

Nakon zatvaranja, kursor postaje nedostupan korisnicima programa. Prilikom zatvaranja uklanjaju se sve brave postavljene tokom njegovog rada. Zatvaranje se može primijeniti samo na otvorene kursore. Zatvoreno, ali ne oslobođen kursor može biti ponovo otvoren. Nije dozvoljeno zatvaranje neotvorenog kursora.

Pustite kursor

Zatvaranje kursora ne oslobađa nužno memoriju koja je s njim povezana. Neke implementacije ga moraju eksplicitno osloboditi koristeći DEALLOCATE izraz. Poslije pustite kursor Memorija se također oslobađa, što omogućava ponovno korištenje imena kursora.

Za kontrolu da li je dosegnut kraj kursora, preporučuje se korištenje funkcije: @@FETCH_STATUS

Funkcija @@FETCH_STATUS vraća:

0 ako je dohvaćanje bilo uspješno;

1 ako dohvaćanje nije uspjelo zbog pokušaja dohvaćanja linije izvan kursora;

2 ako dohvaćanje nije uspjelo zbog pokušaja pristupa izbrisanom ili izmijenjenom redu.

DECLARE @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 "Shopping list" DEKLARI klient_cursor KURSOR LOKALNI ZA ODABIR Šifra klijenta, kompaniju, prezime OD Klijenta GDJE Grad="Moskva" RED PO Kompaniji, Prezime OTVORI klient_cursor PREUZMI SLJEDEĆE IZ klient_cursor U @id_kl, @firm, @T@fam WHILE =0 BEGIN SELECT @message="Klijent "+@fam+ "Kompanija "+ @firm PRINT @message SELECT @message="Naziv proizvoda Datum kupovine Trošak" PRINT @message DECLARE tovar_cursor KURSOR ZA ODABIR Naziv proizvoda, Transaction.Date, Product .Cijena* Transakcija.Količina KAO Trošak IZ INTERNOG PRIDRUŽIVANJA proizvoda Transakcija NA proizvodu. Šifra proizvoda=Transakcija.Šifra proizvoda GDJE Transaction.Customer Code=@id_kl OPEN tovar_cursor DOWN NEXT FROM tovar_cursor INTO @nam, @d, @p IF @@FETCH_STATUS<>0 ŠTAMPAJ "Bez kupovine" DOK @@FETCH_STATUS=0 POČNI ODABIR @message=" "+@nam+" "+ CAST(@d AS CHAR(12))+" "+ CAST(@p AS CHAR(6)) PRINT @message POSTAVI @s=@s+@p DOVEDI DALJE IZ tovar_cursor U @nam, @d, @p END CLOSE tovar_cursor DEALLOCATE tovar_cursor SELECT @message="Ukupni troškovi "+ CAST(@s KAO CHAR(6)) PRINT @message -- premjestiti na sljedećeg klijenta-- DOVEDI SLJEDEĆE IZ klient_cursor U @id_kl, @firm, @fam END CLOSE klient_cursor DEALLOCATE klient_cursor Primjer 13.6. Kursor za prikaz liste robe koju su kupili klijenti iz Moskve i njihove ukupne cijene.

Primjer 13.7. Razvijte kursor koji se može pomicati za klijente iz Moskve. Ako broj telefona počinje sa 1, obrišite klijenta sa tim brojem i u prvom unosu kursora zamijenite prvu cifru u broju telefona sa 4.

DECLARE @firm VARCHAR(50), @fam VARCHAR(50), @tel VARCHAR(8), @message VARCHAR(80) PRINT "Lista klijenata" DECLARE klient_cursor CURSOR GLOBALNI SKROL TESTER ZA IZBOR Firme, Prezime, Telefon OD Klijenta GDJE Grad ="Moskva" NARUDŽI PO Kompaniji, Prezime ZA AŽURIRANJE OTVORI klient_cursor DOVEDI SLJEDEĆE IZ klient_cursor U @firmu, @fam, @tel DOK @@FETCH_STATUS=0 POČNITE ODABIR @message="Klijent "+@fam+ " Kompanija "+ @firm " Phone "+ @tel ŠTAMPAJ @poruku -- ako broj telefona počinje sa 1, -- izbriši klijenta sa tim brojem AKO @tel LIKE '1%' IZBRIŠI klijenta GDJE TRENUTNOST klient_cursor DRUGO -- pređi na sljedeći klijent FETCH NEXT FROM klient_cursor INTO @firm, @fam, @tel END FETCH ABSOLUTE 1 FROM klient_cursor INTO @firm, @fam, @tel -- u prvom unosu zamijenite prvu cifru u broju telefona sa 4 UPDATE Client SET Phone ='4' + DESNO(@ tel,LEN(@tel)-1)) GDJE STRUJA klient_cursor SELECT @message="Klijent "+@fam+" Firma "+ @firma "Telefon "+ @tel PRINT @message CLOSE klient_cursor DEALLOCATE klijent_cursor Primjer 13.7. Kursor koji se može pomicati za klijente iz Moskve.

Primjer 13.8. Upotreba kursor kao izlazni parametar procedure. Procedura vraća skup podataka - listu proizvoda.

Pozivanje procedure i ispis podataka iz izlaznog kursora vrši se na sljedeći način:

DECLARE @my_cur CURSOR DECLARE @n VARCHAR(20) EXEC my_proc @cur=@my_cur IZLAZ DOHVAĆI SLJEDEĆI IZ @my_cur U @n SELECT @n DOK (@@FETCH_STATUS=0) POČNITE DOHVATI SLJEDEĆE IZ @n SELECT @nTO END CLOSE @my_cur DEALLOCATE @my_cur


Kursor je veza do oblasti kontekstualne memorije. U nekim implementacijama SQL programskog jezika (Oracle, Microsoft SQL Server) - skup rezultata dobijen prilikom izvršavanja upita i pridruženi pokazivač trenutnog zapisa. Rekao bih da je kursor virtuelni stošto je alternativno skladište podataka. U ovom slučaju, kursor vam omogućava da pristupite njegovim podacima kao da su podaci regularnog niza.
Kursori se koriste u pohranjenim procedurama. Dosta teorije, pogledajmo primjer:
Imamo bazu podataka (baza podataka je malo loša, ovo je jedna od mojih laboratorijski rad, ali naš nastavnik baze podataka je insistirao na takvoj strukturi)
/*podaci o banci*/
CREATE TABLE `banka` (

`BankName` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,


PRIMARNI KLJUČ (`BankId`)

)ENGINE=InnoDB
SET KARAKTERA "utf8" COLLATE "utf8_bin" ;
/*podaci o depozitima */
CREATE TABLE `bankdistribution` (
`BankId` INTEGER (11) NOT NULL ,
`Persent` INTEGER (11) DEFAULT NULL ,
`ContributeAmount` DECIMAL (10,0) NOT NULL ,
`ClientId` INTEGER (11) NOT NULL ,
PRIMARNI KLJUČ(`BankId`, `ClientId`),
KLJUČ `BankId` (`BankId`),
KLJUČ `ClientId` (`ClientId`),
OGRANIČENJA `bankdistribution_fk` STRANI KLJUČ (`BankId`) REFERENCE `bank` (`BankId`),
OGRANIČENJA `bankdistribution_fk1` STRANI KLJUČ (`ClientId`) REFERENCE `client` (`ClientId`)
)ENGINE=InnoDB
/*podaci o investitorima*/
CREATE TABLE `client` (
`ClientId` INTEGER (3) NOT NULL AUTO_INCREMENT,
`CreditCardId` BIGINT(10) NOT NULL ,
`Prezime` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,
`Naziv` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,
`FirstName` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,
`Telefon` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,
`Adresa` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,
`SafeId` INTEGER (5) NOT NULL ,
PRIMARNI KLJUČ(`ClientId`, `CreditCardId`),
KLJUČ `ClientId` (`ClientId`)

)ENGINE=InnoDB
AUTO_INCREMENT=11 SET KARAKTERA "utf8" COLLATE "utf8_bin"

Recimo da treba da primimo svaku banku redom i izvršimo neke radnje s njom, sljedeći upit bi nam mogao pomoći u tome

Odaberite `banku`.* IZ `banke` OGRANIČEN BROJ_ZAPISA_KOJI NAM TREBAMO,1
. Dakle, koristeći LIMIT WE NEED_RECORD NUMBER, 1, izvlačimo svaki zapis u petlji iz tabele banke i izvodimo radnje koje su nam potrebne, dok povećavamo vrijednost WE NEED_RECORD NUMBER za 1. Sada ćemo učiniti isto, ali koristeći kursor
Počni
/* varijable gdje izdvajamo podatke */
Objaviti vBankId cijeli broj;
Deklarirati vBankName VARCHAR(50);
Objaviti vAddress VARCHAR(50);
Objavite vPhone VARCHAR (50);
/* hadler varijabla - a*/
Deklarirati dovršen integer default 0;
/*Deklaracija kursora*/
Deklarirajte kursor kursora za odabir `banke`.`BankId`,`bank`.`BankName`,`bank`.`Address`,`bank`.`Phone`, FROM `bank` gdje je 1;
/*Svrha HANDLER-a, koja će biti objašnjena u nastavku*/
DECLARE CONTINUE HANDLER ZA SQLSTATE "02000" SET done=1;
/* otvori kursor */
Open BankCursor;
/*preuzmi podatke*/
WHILE done = 0 DO

preduzimamo radnje koje su nam potrebne
END WHILE ;
/*zatvaranje kursora*/
Close BankCursor;
END ;

* Ovaj izvorni kod je istaknut sa izvornim kodom Highlighter.

Greška: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)

Poruka: Nema podataka - nula redova je dohvaćeno, odabrano ili obrađeno

SQLSTATE: 02000 se aktivira kada se dostigne kraj kursora ili kada odabir ili ažuriranje vrati prazan niz.

U sljedećem redu smo deklarirali kursor DECLARE cursor_name CURSOR FOR select_statement;
Otvorite kursor. Otvorite cursor_name;
Zatim, dok ne dođemo do kraja kursora (WHILE done = 0 DO), izvlačimo podatke i obrađujemo ih.
Morate zatvoriti kursor prije izlaska iz pohranjene procedure. Close cursor_name;

Ne izgleda komplikovano. Ali postoje mnoge zamke povezane sa SQLSTATE "02000".

WHILE done = 0 DO
DOVEDI kursor banke U vBankId,vBankName,vAdresa,vPhone;

Odaberite (ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution gdje je BankId = vBankId limit 1;
radimo neke akcije
END WHILE ;

* Ovaj izvorni kod je istaknut sa izvornim kodom Highlighter.


Sve je u redu i korektno sa sintaksnog gledišta. Ali sa logične tačke gledišta, ne. Može se desiti da deponenti nisu otvorili račune u nekoj banci, a zatim za Select (ContributeAmount) INTO vContributeAmountSUM IZ distribucije banke gde je BankId = vBankId limit 1; SQLSTATE: 02000 će se pokrenuti, varijabla done će biti postavljena na 1, i while petlja završiti ranije nego što smo očekivali. Ovo se može izbjeći na sljedeći način
WHILE done = 0 DO
DOVEDI kursor banke U vBankId,vBankName,vAdresa,vPhone;
/* izvući za banku iznos bilo kojeg njenog depozita */


if (vContributeAmountSUM > 0) onda
/* izvući za banku iznos bilo kojeg njenog depozita */

kraj ako ;
radimo neke akcije
END WHILE ;

* Ovaj izvorni kod je istaknut sa izvornim kodom Highlighter.


Prvim zahtjevom smo provjerili da li ima doprinosa (ako ih nema, onda vContributeAmountSUM == 0) i tek ako ih ima, preuzimamo podatke.

Sada recimo da moramo ukloniti ukupan iznos na računima u različitim bankama za svakog klijenta
Objavite ClientSummCursor kursor za Odaberite zbroj

Objavite ClientSummCursor kursor za Odabir sume (`bankdistribution`.`ContributeAmount`), `bankdistribution`.`ClientId` IZ `bankdistribution` Inner Join klijenta na (client.ClientId = bankdistribution.`ClientId`) gdje je 1 grupa distribucije po `banki. `ClientId`;

Open ClientSummCursor;
WHILE done = 0 DO
DOVEDI kursor banke U vBankId,vBankName,vAdresa,vPhone;
/* izvući za banku iznos bilo kojeg njenog depozita */
Odaberite Count(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution gdje je BankId = vBankId limit 1;
/* provjerite da li zaista ima depozita u ovoj banci */
if (vContributeAmountSUM > 0) onda
/* izvući za banku iznos bilo kojeg njenog depozita */
Odaberite ContributeAmount INTO vContributeAmountSUM FROM bankdistribution gdje je BankId = vBankId limit 1;
kraj ako ;


radimo neke akcije.
END WHILE ;

* Ovaj izvorni kod je istaknut sa izvornim kodom Highlighter.

Ista situacija može nastati kada se podaci u ClientSummCursor kursoru završe ranije od podataka u BankCursoru, SQLSTATE: 02000 se aktivira, varijabla done je postavljena na 1, a while petlja završava ranije nego što smo očekivali. Ovo se može izbjeći na sljedeći način

Open ClientSummCursor;
WHILE done = 0 DO
DOVEDI kursor banke U vBankId,vBankName,vAdresa,vPhone;
/* izvući za banku iznos bilo kojeg njenog depozita */
Odaberite Count(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution gdje je BankId = vBankId limit 1;
/* provjerite da li zaista ima depozita u ovoj banci */
if (vContributeAmountSUM > 0) onda
/* izvući za banku iznos bilo kojeg njenog depozita */
Odaberite ContributeAmount INTO vContributeAmountSUM FROM bankdistribution gdje je BankId = vBankId limit 1;
kraj ako ;
/* prije izvlačenja podataka iz drugog kursora, zapamtite stanje sqlstate */
SET old_status = gotovo;
/* izdvojiti podatke koji su nam potrebni */
DOHVATI ClientSummCursor INTO vSum,vClientId;
/* provjeriti da li su podaci preuzeti i da li sqlstate 0200 nije uspio */
if (urađeno = 0) onda
radimo neke akcije.
kraj ako ;
/* prije isteka vremena, vrati vrijednost urađene varijable */
set done = old_status;
END WHILE ;

* Ovaj izvorni kod je istaknut sa izvornim kodom Highlighter.

Hvala svima koji su čitali do sada, nadam se da će ovo nekome biti od koristi.

ODNOSI SE NA: SQL Server (od 2008.) Baza SQL podaci Azure SQL skladište podataka Paralelno skladište podataka

Definira atribute kursora Transact-SQL servera, kao što su svojstva pogleda i upit koji se koristi za izgradnju skupa rezultata na kojem kursor radi. Naredba DECLARE CURSOR podržava i sintaksu ISO standarda i sintaksu koja koristi Transact-SQL skup proširenja jezika.

ISO sintaksa DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR FOR select_satement [ FOR ( SAMO ČITANJE | UPDATE [ OF column_name [ ,...n ] ] ) ] [;] Transact-SQL proširena sintaksa DECLARE cursor_name CURSOR [ LOCAL | GLOBALNO ] [ FORWARD_ONLY | SKROL ] [ STATIČNO | KEYSET | DYNAMIC | FAST_FORWARD ] [ SAMO ČITANJE | SCROLL_LOCKS | OPTIMISTIČNO ] [ TYPE_WARNING ] ZA select_satement [ ZA AŽURIRANJE [ OF column_name [ ,...n ] ] ] [;]

cursor_name
cursor_name

NEOSJETLJIV
tempdb; stoga se promjene osnovnih tabela ne odražavaju u podacima koje vraćaju odabiri ovog kursora, a ovaj kursor nije promjenjiv. Kada koristite ISO sintaksu, osim ako nije specificirana opcija INSENSITIVE, predana ažuriranja i brisanja napravljena u osnovnim tablicama pojavljuju se u narednim odabirima.

SCROLL
Označava da su dostupne sve opcije uzorkovanja (PRVI, POSLEDNJI, PRETHODNI, SLEDEĆI, RELATIVNI, APSOLUTNI). Ako ISO DECLARE CURSOR izraz ne specificira opciju SCROLL, podržana je samo opcija NEXT dohvaćanja. Opcija SCROLL se ne može specificirati s opcijom FAST_FORWARD.

select_statement
Standard SELECT izraz, koji definira skup rezultata kursora. Ključne riječi ZA BROWSE i INTO nisu dozvoljeni select_statement deklaracija kursora.

select_statement sukob sa kursorom traženog tipa.

SAMO ZA ČITANJE

Ažuriraj ]
column_name [, .. .n] je naveden, samo navedene kolone dozvoljavaju promjene. Ako se izraz UPDATE koristi bez liste stupaca, tada je ažuriranje moguće za sve stupce.

cursor_name
Transact-SQL ime određenog kursora servera. cursor_name moraju poštovati pravila za identifikatore.

LOCAL
Označava da je kursor lokalni za paket, pohranjenu proceduru ili okidač u kojem je kreiran. Ime kursora je važeće samo unutar ovog područja. Kursor se može referencirati pomoću lokalnih varijabli paketa, pohranjenih procedura, okidača ili izlaznog parametra pohranjene procedure. Parametar OUTPUT se koristi za prosljeđivanje lokalnog kursora pozivnom paketu, pohranjenoj proceduri ili okidaču, koji zatim može dodijeliti parametar varijabli kursora za naknadni pristup kursoru nakon što se pohranjena procedura završi. Kursor se implicitno otpušta kada serija, pohranjena procedura ili okidač dovrše izvršenje, osim ako kursor nije proslijeđen parametru OUTPUT. Ako je kursor proslijeđen parametru OUTPUT, kursor se oslobađa kada se oslobode sve varijable koje ga upućuju ili kada se izađe iz opsega.

GLOBALNO
Označava da je kursor globalan za vezu. Ime kursora može koristiti bilo koja pohranjena procedura ili paket koji se izvodi na vezi. Kursor se implicitno pušta samo ako je veza prekinuta.

FORWARD_ONLY
Određuje da se kursor može vidjeti samo od prvog do posljednjeg reda. Podržana je samo opcija dohvaćanja FETCH NEXT. Ako je FORWARD_ONLY specificirano bez ključnih riječi STATIC, KEYSET ili DYNAMIC, kursor se ponaša kao DYNAMIC kursor. Ako nisu navedeni ni argument FORWARD_ONLY ni argument SCROLL, default je argument FORWARD_ONLY osim ako nisu prisutne ključne riječi STATIC, KEYSET ili DYNAMIC. STATIČKI, KEYSET i DYNAMIC kursori imaju zadanu vrijednost SCROLL. Za razliku od API-ja baze podataka kao što su ODBC i ADO, režim FORWARD_ONLY podržavaju sljedeći Transact-SQL kursori: STATIC, KEYSET i DYNAMIC.

STATIC
Definira kursor koji kreira privremenu kopiju podataka za korištenje od strane kursora. Svi upiti prema kursoru pristupaju navedenoj privremenoj tabeli u tempdb; stoga se promjene osnovnih tabela ne odražavaju u podacima koje vraćaju odabiri ovog kursora, a ovaj kursor nije promjenjiv.

KEYSET
Označava da je članstvo ili redoslijed redova u kursoru nepromijenjeni kada se otvori. Skup ključeva koji jedinstveno identificiraju redove ugrađen je u tablicu tempdb pozvao ključevi.

Promjene neključnih vrijednosti u osnovnim tabelama koje je napravio vlasnik kursora ili koje su izvršili drugi korisnici prikazuju se kada ih vlasnik kursora pregleda. Promjene koje su napravili drugi korisnici se ne odražavaju (promjene se ne mogu napraviti pomoću kursora Transact-SQL servera). Ako je red izbrisan, pokušaj preuzimanja redova vraća @@FETCH_STATUS -2. Ažuriranja ključnih vrijednosti zbog granica kursora su slična brisanju starog reda i zatim ga umetanju nova linija. Red sa novim vrednostima nije vidljiv i pokušava da dohvati red sa starim vrednostima vraća @@FETCH_STATUS -2. Ažuriranja su vidljiva odmah ako se izvrše preko kursora koristeći klauzulu WHERE CURRENT OF.

DYNAMIC
Definira kursor koji prikazuje sve promjene podataka napravljene u redovima u skupu rezultata dok gledate ovaj kursor. Vrijednosti podataka, redoslijed i članstvo u redovima u svakom odabiru mogu varirati. Opcija APSOLUTNOG odabira nije podržana od strane dinamičkih kursora.

BRZO NAPRIJED
Označava kursor FORWARD_ONLY, READ_ONLY koji ima omogućenu optimizaciju performansi. Opcija FAST_FORWARD se ne može specificirati sa opcijama SCROLL ili FOR_UPDATE.

SAMO ZA ČITANJE
Sprječava promjene napravljene putem ovog kursora. WHERE CURRENT OF klauzula ne može referencirati kursor u UPDATE ili DELETE izrazu. Ova opcija ima prednost nad zadanom funkcijom osvježavanja kursora.

SCROLL_LOCKS
Označava da će pozicionirana ažuriranja ili brisanja napravljena pomoću kursora zajamčeno uspjeti. SQL Server zaključava redove dok se čitaju u kursor kako bi osigurao da su ti redovi dostupni za naredne promjene. Opcija SCROLL_LOCKS se ne može specificirati s opcijom FAST_FORWARD ili STATIC.

OPTIMISTIČNO
Određuje da pozicionirana ažuriranja ili brisanja napravljena pomoću kursora neće uspjeti ako je red ažuriran otkako je učitan u kursor. SQL Server ne zaključava redove dok se čitaju u kursor. Umjesto toga se koriste poređenja vremenska oznaka vrijednosti stupaca ili kontrolni zbroji ako tabela nema vremenska oznaka stupcu da odredite da li se red promijenio otkako je pročitan u kursor. Ako je red izmijenjen, pokušaji pozicioniranog ažuriranja ili brisanja neće uspjeti. Opcija OPTIMISTIC se ne može specificirati s opcijom FAST_FORWARD.

TYPE_WARNING
Određuje da će se upozorenje poslati klijentu ako se kursor implicitno konvertuje iz jednog traženog tipa u drugi.

select_statement
Standardni SELECT izraz koji specificira skup rezultata kursora. Ključne riječi COMPUTE, COMPUTE BY, FOR BROWSE i INTO nisu dozvoljene u select_statement deklaracija kursora.

SQL Server implicitno pretvara kursor u drugi tip ako su klauzule u select_statement sukob sa kursorom traženog tipa. Za više informacija pogledajte Implicitne konverzije kursora.

ZA AŽURIRANJE ]
Definira stupce u kursoru koji će se ažurirati. Ako je OF column_name [, ... n], samo navedene kolone dozvoljavaju promjene. Ako se naredba UPDATE koristi bez liste stupaca, tada je ažuriranje moguće za sve stupce osim ako nije specificirana opcija istodobnosti READ_ONLY.

Naredba DECLARE CURSOR definira atribute kursora Transact-SQL servera, kao što su svojstva pogleda i upit koji se koristi za izgradnju skupa rezultata na kojem kursor radi. Naredba OPEN popunjava skup rezultata, a naredba FETCH vraća red iz njega. Naredba CLOSE briše trenutni skup rezultata povezan sa kursorom. Naredba DEALLOCATE oslobađa resurse koje koristi kursor.

Prvi oblik naredbe DECLARE CURSOR koristi ISO sintaksu za specificiranje parametara kursora. Drugi oblik naredbe DECLARE CURSOR koristi proširenja za jezik Transact-SQL koja vam omogućavaju da definirate kursore koristeći iste tipove koji se koriste u funkcijama kursora API-ja baze podataka kao što su ODBC i ADO.

Ova dva oblika se ne mogu mešati. Ako navedete SCROLL ili izostavite ključne riječi prije ključne riječi CURSOR, ne možete koristiti ključne riječi između CURSOR i također za select_statement ključne riječi. Prilikom navođenja ključnih riječi između CURSOR-a, kao i za select_statement ključne riječi, ne možete specificirati SCROLL ili INSENSITIVE prije ključne riječi CURSOR.

Ako koristite Transact-SQL sintaksu za izraz DECLARE CURSOR i ne specificirate opcije READ_ONLY, OPTIMISTIC ili SCROLL_LOCKS, pretpostavlja se sljedeća zadana vrijednost.

    Ako izraz SELECT ne podržava ažuriranja (ili nema dovoljne dozvole, ili pristupa udaljenim tablicama koje ne podržavaju ažuriranja, itd.), kursor je postavljen na READ_ONLY.

    STATIC i FAST_FORWARD kursori su zadani na READ_ONLY.

    DYNAMIC i KEYSET kursori su zadani na OPTIMISTIČNO.

Kurzori se mogu referencirati samo drugim Transact-SQL izrazima. Funkcije API-ja baze podataka ne mogu referencirati kursore. Na primjer, kada je kursor deklariran, funkcije i metode OLE DB, ODBC ili ADO ne mogu se odnositi na njegovo ime. Redovi kursora se ne mogu odabrati pomoću odgovarajućih API funkcija i metoda; U tu svrhu morate koristiti Transact-SQL FETCH izraze.

Sljedeće pohranjene procedure mogu se koristiti za definiranje svojstava kursora nakon što je deklariran.

Varijable se mogu koristiti kao dio select_statement, u kojem je deklarisan kursor. Vrijednosti varijabli kursora se ne mijenjaju nakon što je deklarirana.

Prema zadanim postavkama, dozvole DECLARE CURSOR se dodjeljuju svim korisnicima koji imaju dozvolu SELECT za poglede, tabele i stupce koje koristi kursor.

Ne možete koristiti kursore ili okidače na tablici s klasteriranim indeksom pohrane stupaca. Ovo ograničenje se ne primjenjuje na indekse koji nisu klasterirani; Možete koristiti kursore i okidače na tablici s neklasteriranim indeksom pohrane stupaca.

A. Korišćenje jednostavnog kursora i sintakse

Skup rezultata kreiran kada otvorite ovaj kursor uključuje sve redove i stupce tabele. Ovaj kursor se može ažurirati, sva ažuriranja i brisanja su predstavljena u odabiru za ovaj kursor. FETCH``NEXT se dohvaća samo zato što parametar SCROLL nije specificiran.

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

B. Upotreba ugniježđenih kursora za prikaz izvještaja

Sljedeći primjer koristi ugniježđene kursore za prikaz složenog izvještaja. Za svakog provajdera je deklarisan interni kursor.

SET NOCOUNT ON ; DECLARE @vendor_id int, @vendor_name nvarchar (50), @message varchar (80), @product nvarchar (50);ŠTAMPAJ" -------- Izvještaj o proizvodima dobavljača --------"; DECLARE vendor_cursor CURSOR ZA SELECT VendorID, Name FROM Purchasing.Vendor WHERE PreferredVendorStatus = 1 ORDER BY VendorID; OPEN vendor_cursor FETCH NEXT FROM vendor_cursor INTO @vendor_id, @vendor_name DOK @@FETCH_STATUS = 0 POČNI ŠTAMPANJE " " SELECT @message = "----- Proizvodi od dobavljača: "+ @vendor_name ŠTAMPAJ @poruku -- Deklarirajte baziran na unutrašnjem kursoru -- na vendor_id iz vanjskog kursora. DECLARE product_cursor CURSOR ZA SELECT v.Name FROM Purchasing.ProductVendor pv, Production.Product v WHERE pv.ProductID = v.ProductID AND pv.VendorID = @vendor_id -- Varijabilna vrijednost iz vanjskog kursora OPEN product_cursor FETCH NEXT FROM product_cursor INTO @product IF @@FETCH_STATUS<>0 ŠTAMPA "<>" DOK @@FETCH_STATUS = 0 POČNI ODABIR @message = " " + @product PRINT @message DOVEDI SLJEDEĆE IZ product_cursor U @product END CLOSE product_cursor DEALLOCATE product_cursor -- Uzmi sljedećeg dobavljača. DETCH NEXT OD vendor_cursor INTO @vendor_id END CLOSE vendor_cursor; DEALLOCATE vendor_cursor;

Može se dogoditi da odgovor na jednostavan zahtjev klijenta bude uzorak od stotina hiljada redova, što je za većinu klijenata neprobavljivo. U ovom slučaju, rješenje problema interakcije s klijentima je korištenje kursora kao univerzalnog mehanizma za razmjenu podataka između servera i klijenta. Kursori rade sa skupom rezultata (rezultat upita), dajući korisnicima dodatne mogućnosti obrade podataka:

Kursori vam omogućavaju da radite sa redovima tabele navodeći njihov serijski broj u skupu podataka;

Kursori vam omogućavaju da implementirate složene operacije modifikacije podataka, na primjer, kada promjena vrijednosti stupca zahtijeva uzastopno pristupanje vrijednostima drugih stupaca.

Životni ciklus kursora:

Kreiranje kursora: DECLARE<имя курсора>[ NEOSJETLJIV ] [ KROZ ] KURSOR ZA< SELECT -оператор>ZA (SAMO ZA ČITANJE | AŽURIRANJE)

Ovdje ključna riječ INSENSITIVE znači da će kursor biti statičan (snimka podataka), dok je po defaultu kursor kreiran dinamički (dohvaćanje se vrši svaki put kada se pristupi redu). Ključna riječ SCROLL znači da se kursor može pomicati u bilo kojem smjeru, inače se kursor kreira kao "sekvencijalni" kursor.

Kursor za otvaranje: OTVORENO [GLOBALNO]<имя курсора>. Kursor naveden kao GLOBAL se ne briše automatski kada se završi procedura ili paket iz kojeg je pozvan.

Čitanjepodaci : DETCH [[ SLJEDEĆA | PRIOR | PRVI | POSLEDNJA | APSOLUTNI n | RELATIVNI n ] OD ] [ GLOBALNO ]<имя курсора>[INTO@ime_varijable,...]. SQL Server 2000 vam omogućava da čitate samo jedan red iz kursora. FIRST ključna riječ je da vrati prvi red kursora; LAST – posljednji red kursora; NEXT – sljedeći red nakon tekućeg, vraćeni red postaje trenutni; PRIOR – prethodni prije tekućeg; ABSOLUTE n – vraća liniju po njenom apsolutnom redoslijedu u kursoru; RELATIV – n reda iza trenutnog. Podaci stupca bit će pohranjeni u svakoj od navedenih varijabli onim redoslijedom kojim su navedeni.

Promjena podataka: izvršava naredbu UPDATE sa sintaksom dizajniranom za rad sa kursorima.

Brisanje podataka: izvršava naredbu DELETE sa sintaksom dizajniranom za rad sa kursorima.

Zatvaranje kursora: ZATVORI [GLOBALNO]<имя курсора>

Pustite kursor: ODLOČI [GLOBALNO]<имя курсора>

Primjer korištenja kursora:

DECLARE fo_curs CURSOR STATIC ZA

SELECT name_rus iz fo ORDER BY name_rus

DECLARE @name varchar(50)

PREUZMI PRVO IZ fo_curs INTO @name

WHILE @@FETCH_STATUS=0

PREUZMI SLJEDEĆE IZ fo_curs U @name

DEALLOCATE fo_curs

2.7. Osiguravanje sigurnosti i integriteta podataka u Microsoft SQL Serveru. Upravljanje bazom podataka. Uloge. Dodjela prava korisnicima (GRANT, DENY, REVOKE). Metode i tehnologije za zaštitu podataka u SQL Serveru.

Sigurnost i administracija SQL Servera. .

Glavni zadatak DBMS-a je da osigura integritet i konzistentnost podataka unutar odabranog predmetnog područja. Jedan od faktora koji sprečavaju sistem da reši ovaj problem su radnje korisnika koji slučajno ili namerno pokušavaju da unište strukturu podataka ili promene same podatke. Shodno tome, DBMS mora biti zaštićen ne samo od fizičkih kvarova, već i od korisnika koji su neadekvatni za zadatke koji se implementiraju. Da biste to učinili, potrebno je dizajnirati i povezati sigurnosni sistem na bazu podataka koji će spriječiti korisnike da izvršavaju radnje izvan njihovih ovlaštenja.

Upravljanje bazom podataka

Da biste kreirali bazu podataka koristeći TSQL, koristite naredbu CREATE DATABASE, ali se obično u tu svrhu koriste mogućnosti SQL Server Management Studio-a. IN SQL server definirano je dosta operacija baze podataka: povećanje (smanjenje) veličine datoteka, promjena konfiguracije (naredba ALTER), pripajanje i odvajanje, prijenos vlasništva, promjena imena, pregled svojstava i, konačno, brisanje (DROP DATABASE).

Kao i većina servera baza podataka, SQL Server ima korisnika s punim administrativnim pravima - to jest Administrator sistema ili "sa". Nakon početne instalacije servera, sa lozinka je prazna. Korisnik koji kreira novu bazu podataka automatski postaje njen vlasnik ('dbo' - Vlasnik baze podataka). U trenutku kreiranja baze podataka definiran je i korisnik "gost". Ako korisnički račun nije eksplicitno mapiran na korisnika određenoj bazi podataka, korisniku se odobrava implicitni pristup uz korištenje imena gosta guest.Guest je obično zabranjen.

Korisnik koji kreira objekat u bazi podataka automatski postaje njen vlasnik i niko, uključujući dbo i sa, ne može koristiti taj objekat dok im vlasnik ne dodeli prava na njega. Ali da bi korisnik mogao kreirati objekat, vlasnik baze podataka mora mu prvo dati odgovarajuća prava.

Uloga omogućava vam kombiniranje korisnika koji obavljaju iste funkcije kako biste pojednostavili administraciju. Uloge mogu biti ugrađene ili prilagođene. Ugrađene uloge se implementiraju na nivou servera i na nivou baze podataka. Ispod je tabela uloga ugrađene baze podataka:

db_owner. Posjeduje sva prava na bazu podataka

Db_accessadmin. Može dodavati ili uklanjati korisnike

Db_securityadmin. Upravlja svim dozvolama, objektima, ulogama i korisnicima

Db_ddladmin. Može izvršiti sve DDL naredbe osim GRANT, DENY, REVOKE

Db_backupoperator. Arhivar može da izvršava komande. podaci

db_datareader. Možda gledanje. bilo koji podatak u bilo kojoj tabeli

db_datawriter. Možda modifikacija. bilo koji podatak u bilo kojoj tabeli

Db_denydatareader. Zabranjeno pogled ljubav podataka u bilo kom stolovi

Db_denydatawriter. Zabrana izmjene bilo kojih podataka u bilo kojoj tabeli

Dodjela prava korisnicima. Osnova sigurnosti SQL Servera je (1) Računi(računi); (2) korisnici; (3) uloge; (4) grupe.

Kada se korisnik poveže na SQL Server, radnje koje može izvršiti određuju se pravima koja su mu data kao korisniku i članu uloge. Prava dodjeljuje administrator DBMS-a, vlasnik baze podataka ili vlasnik određenog objekta baze podataka. Prava u bazi podataka mogu se podijeliti u tri kategorije: (1) prava pristupa objektima baze podataka; (2) prava za izvršavanje TSQL komandi; (3) implicitna prava. Server vam omogućava da prenesete vlasništvo sa jednog korisnika na drugog.

Sljedeće naredbe se koriste za upravljanje korisničkim dozvolama za pristup objektima baze podataka:

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

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

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

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

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

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

dodeljivanje prava korisnicima, Gdje

SVE – korisniku se odobravaju sve moguće dozvole, inače navedite

<вид действия>– prava na radnje koje su dostupne korisniku, i to:

SELECT – za pogled, za kolonu tabele i za tabelu (pregled)

INSERT – dodati, za tabelu (pregled) u celini

UPDATE – za promjenu, za kolonu tabele i za tabelu (pregled)

IZBRIŠI – brisati, za tabelu (pregled) u cjelini

EXECUTE – za izvršavanje pohranjenih procedura

REFERENCE – sposobnost upućivanja na određeni objekt (uključiti ga kao dio stranog ključa).

<имя объекта системы безопасности>– SQL Server nalozi, korisnici Windows domena; JAVNO – za sve korisnike.

SA OPCIJOM GRANT - omogućava korisniku kojem su trenutno odobrena prava da dodijeli prava pristupa objektu drugim korisnicima.

AS<имя группы> | <имя роли>– učešće korisnika u ulozi kojoj je data mogućnost da dodeljuje prava drugim korisnicima.

ODOBRITE SELECT ON autorima javnosti

GRANT UMETNI, AŽURIRAJ, IZBRIŠI autore Mary, Johnu, Tomu

GRANT SELECT ON Plan_Data za računovodstvo SA OPCIJOM DODAVANJA

GRANT SELECT ON Plan_Data TO Jack AS Accounting

Jack nije član računovodstvene uloge, ali neko u toj ulozi može dati dozvolu

DENY(SVE |< вид действия >,…}

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

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

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

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

uskraćivanje pristupa korisnika na objekte baze podataka. CASCADE ukida prava ne samo od datog korisnika, ali i za svakoga kome je dao prava.

Primjer (uključeno komandna zabrana TSQL):

ODBIJAJTE PRAVLJANJE TABLE Jacku CASCADE

Tim REVOKE koristi se za implicitno uskraćivanje pristupa objektima baze podataka. Sintaksa je ista kao naredba DENY. Implicitno uskraćivanje je slično odbijanju pristupa, osim što se primjenjuje samo na nivou na kojem je definirano. Primjer: Korisnik Jack, koji je član uloge GoodUsers, ima pravo pristupa XFiles tabeli. Ako je REVOKE odbijen za ulogu GoodUsers da pristupi ovoj tablici, Jack i dalje može pristupiti ovoj tablici jer su prava za njega eksplicitno definirana. Ako koristite REVOKE lično za njega, on će izgubiti pravo na pristup XFiles-u.

Dozvole dodijeljene ulogama nasljeđuju njihovi članovi. Ako je korisniku odobren pristup objektu kroz članstvo u jednoj ulozi, ali odbijen u drugoj, tada se sukob pristupa uvijek rješava u korist odbijanja.

Tehnologije zaštite podataka u MS SQL Serveru

1.Mehanizam kontrolne tačke– kontrolne tačke koje se generišu nakon ~60 s za pisanje ažuriranih stranica na disk (kontrolna tačka se može forsirati naredbom CHECKPOINT).

2. Ugrađeni i eksterni mehanizmi za provjeru integriteta baze podataka (pokreću se automatski ili, poput DBCC uslužnog programa - Database Consistency Checker - ručno).

3.Fizičko umnožavanje (ako je dozvoljeno) datoteka baze podataka koristeći operativni sistem (uključujući mehanizam preslikanih tvrdih diskova).

4. Pravljenje rezervne kopije baza podataka i evidencije transakcija - pisanjem dumpa baze podataka na uređaj za rezervnu kopiju (magnetna traka ili čvrsti disk).

5. Replikacija – mogućnost dupliciranja informacija periodičnim (u nekim slučajevima, sinhronim) prijenosom sa jednog SQL servera na drugi.

6. Šifrovanje saobraćaja između klijenta i servera, kao i šifrovanje kodova koji se koriste za rad sa objektima baze podataka (pohranjene procedure, okidači, itd.)

1) Koncept kursora
Interaktivni SQL ne pravi razliku između jednorednih i višerednih upita. Ugrađeni SQL izvršava ove upite drugačije. Jednoredni upiti vraćaju jednu liniju i već smo ih pokrili. Kada je rezultat upita više od jednog reda, ugrađeni SQL mora dozvoliti aplikaciji da dohvati rezultate upita red po red. Za to se koriste kursori. Kursor je varijabla povezana s upitom. Njegova vrijednost je svaki red koji odgovara upitu. Kao i varijable, kursori moraju biti deklarisani prije nego što se mogu koristiti. Za razliku od pogleda, kursori su dizajnirani za obradu red po red.

2) Deklaracija kursora

DECLARE [{}] [[NO] SCROLL] CURSOR [{SA|BEZ} HOLD] ZA [ZA {SAMO ČITANJE|AŽURIRANJE [OF ]}]

3) Ključne riječi
. OSJETLJIVO|NEOSJETLJIVO|OSJETLJIVO– vidljive su promjene u skupu rezultata | zabranjeno (popravljeno upotrebom kopije skupa podataka)|DBMS sam odlučuje hoće li napraviti kopiju (radi po defaultu).
. SA|BEZ ČEKANJA– ostavlja otvoreno | zatvara kursor ako se naiđe na COMMIT izraz.
. SCROLL– [spriječava] izdvajanje redova rezultata po slučajnom redoslijedu.
. SAMO ZA ČITANJE– definira kursor samo za čitanje.
. ZA AŽURIRANJE– blokira ažuriranje samo navedenih kolona.

4) Deklarisanje kursora u SQL Serveru

DECLARE CURSOR [LOKALNO|GLOBALNO] [FORWARD_ONLY|SCROLL] [STATIČKI|SET TIPOVA|DINAMIČKI|FAST_FORWARD] [READ_ONLY|SCROLL_LOCKS|OPTIMISTIČNO] ZA [ZA AŽURIRANJE [OF ]]

. STATIC– Definira kursor koji kreira privremenu kopiju podataka za korištenje od strane kursora. Svi upiti prema kursoru pristupaju navedenoj privremenoj tablici u bazi podataka tempdb, tako da promjene u osnovnim tabelama ne utiču na podatke koje vraćaju uzorci za taj kursor, a sam kursor ne dozvoljava unošenje promjena.
. KEYSET– Označava da se članstvo ili redoslijed redova u kursoru ne mijenja nakon što se otvori. Skup ključeva koji jedinstveno identificiraju redove ugrađen je u tablicu u bazi podataka tempdb koja se zove set ključeva.
. DYNAMIC– Definira kursor koji prikazuje sve promjene podataka napravljene u redovima skupa rezultata prilikom pregleda ovog kursora. Vrijednosti podataka, redoslijed i članstvo u redovima u svakom odabiru mogu varirati. Opcija APSOLUTNOG odabira nije podržana od strane dinamičkih kursora.
. BRZO NAPRIJED– Označava kursor FORWARD_ONLY, READ_ONLY za koji je omogućena optimizacija performansi. Opcija FAST_FORWARD se ne može specificirati sa opcijama SCROLL ili FOR_UPDATE.
. SCROLL_LOCKS– Označava da će pozicionirana ažuriranja ili brisanja putem kursora zajamčeno uspjeti. SQL Server zaključava redove dok se čitaju u kursor kako bi se osiguralo da su dostupni za naredne promjene. Opcija SCROLL_LOCKS se ne može specificirati s opcijom FAST_FORWARD ili STATIC.
. OPTIMISTIČNO– Označava da pozicionirana ažuriranja ili brisanja izvršena kroz kursor neće uspjeti ako je red ažuriran od trenutka kada je učitan u kursor. SQL Server ne zaključava redove dok se čitaju u kursor. Umjesto toga, pravi se poređenje vrijednosti kolone vremenske oznake (ili kontrolnih suma ako tabela nema kolonu vremenske oznake) kako bi se utvrdilo da li se red promijenio otkako je pročitan u kursor. Ako je red izmijenjen, njegova pozicionirana izmjena ili brisanje nije moguća. Opcija OPTIMISTIC se ne može specificirati s opcijom FAST_FORWARD.

5) Otvaranje kursora

6) Dohvaćanje redova iz kursora

FETCH [{SLJEDEĆA|PRIJAVA|PRVA|POSLJEDNJA|{APSOLUTNO|RELATIVNO }}]
OD INTO

7) Opcije pozicioniranja kursora
. SLJEDEĆA|PRIJAVA|PRVA|POSLJEDNJA– na sljedeći|prethodni|prvi|poslednji red skupa rezultata.
. RELATIVNO ±N– na liniju sa pozitivnim ili negativnim pomakom u odnosu na trenutnu liniju.
. APSOLUTNO ±N– na red s eksplicitno specificiranim apsolutnim brojem pozicije od početka ili kraja kursora.

Bilješka: SQL Server dozvoljava cjelobrojnu varijablu @N umjesto N.

8) Zatvaranje kursora

9) Napomene o kursorima
. Ako kursor sadrži više od jedne linije, potrebno je organizirati petlju za dohvaćanje podataka iz njega, periodično provjeravajući da dođe do posljednjeg reda.
. Za razliku od tabela i pogleda, redovi kursora su poredani ili eksplicitno pomoću sekcije POREDAK PO, ili u skladu sa konvencijama usvojenim u određenom DBMS-u.
. Kursori se također koriste za odabir grupa redova iz tabela, koje se mogu ažurirati ili brisati jedan po jedan.
. Da bi kursor mogao da se ažurira, mora da ispunjava iste kriterijume kao i pogled, odnosno da ne sadrži sekcije UNION, RED PO, GRUPA PO, DISTINCT.

10) Primjer za brisanje podataka iz kursora

exec sql deklarirati kursor Cur1 za odabir * od Kupca
gdje Ocjena
// print (@f1+’ ‘+convert(Varchar(5),@f2))
exec sql delete iz Customer
gdje je struja Cur1; ) – Uzmite podatke za brisanje iz kursora
nije urađeno:
exec sql zatvori kursor Cur1; — Zatvorite kursor
Izlaz();

11) Primjer povećanja provizija

exec sql deklarirati kursor CurCust za odabir * iz SalesPeople
gdje je SNum u (odaberite SNum od Kupca gdje je Ocjena=300); — Definišite kursor
exec sql otvori kursor CurCust; - Izvršite kursor
while (sqlca.sqlcode==0) ( — Kreirajte petlju za ažuriranje podataka u tabeli
exec sql dohvati CurCust u:Id_num, :SalesPerson, :Loc, :Comm;
exec sql ažuriranje SalesPeople postavlja Comm=Comm+.01 gdje je trenutno
of CurCust; ) – Uzmite podatke za ažuriranje sa kursora
exec sql zatvori kursor CurCust; — Zatvorite kursor

SELECT S.Name, MAX(S.City) AS City, SUM(O.Amt) AS AMT FROM SalesPeople S INNER JOIN Narudžbe O ON S.SNum=O.SNum GROUP BY S.Name ORDER BY 2

DECLARE Cur1 SCROLL CURSOR ZA ODABIR S.Name, MAX(S.City) KAO Grad, SUM(O.Amt) KAO Iznos OD SalesPeople S INNER JOIN Narudžbe O ON S.SNum=O.SNum GRUPA PO S.Name ORDER BY 2
OPEN Cur1
PREUZMI SLJEDEĆE IZ Cur1
WHILE @@FETCH_STATUS=0
POČNI
PREUZMI SLJEDEĆE IZ Cur1
KRAJ
CLOSE Cur1
DEALLOCATE Cur1