Fjerner fra ms sql-markøren. Markører i MySQL lagrede prosedyrer. A. Bruke en enkel markør og syntaks

Definisjonen av markøren er gitt. En beskrivelse av dens typer og oppførsel er gitt: statiske, dynamiske, sekvensielle og nøkkelmarkører. Prinsippene for markørkontroll er beskrevet: opprette og åpne en markør, lese data, lukke en markør. Eksempler på markørprogrammering er gitt.

Markør konsept

Be om å relasjonsdatabase data returnerer vanligvis flere rader (poster) med data, men applikasjonen behandler bare én post om gangen. Selv om den omhandler flere rader samtidig (for eksempel visning av data i form av regneark), er antallet fortsatt begrenset. I tillegg, når du endrer, sletter eller legger til data, er arbeidsenheten serien. I denne situasjonen kommer begrepet markør i forgrunnen, og i denne sammenhengen er markøren en peker til en rad.

En markør i SQL er et område i databaseminnet som er designet for å inneholde den siste SQL-setningen. Hvis den gjeldende setningen er en databasespørring, lagres også en rad med spørringsdata kalt gjeldende verdi, eller gjeldende markørlinje, i minnet. Det angitte området i minnet er navngitt og tilgjengelig for applikasjonsprogrammer.

Vanligvis brukes markører til å velge fra en database en delmengde av informasjonen som er lagret i den. En markørlinje kan til enhver tid kontrolleres av applikasjonsprogrammet. Pekere brukes ofte i SQL-setninger som er innebygd i applikasjonsprogrammer skrevet på prosedyrespråk. Noen av dem er implisitt opprettet av databaseserveren, mens andre er definert av programmerere.

I samsvar med SQL-standarden, når du arbeider med markører, kan følgende hovedhandlinger skilles:

  • skapelsen eller markørerklæring;
  • åpningsmarkøren, dvs. fylle den med data som er lagret i multi-level minne;
  • valg fra markøren og endre datarader med den;
  • lukker markøren, hvoretter det blir utilgjengelig for brukerprogrammer;
  • frigjør markøren, dvs. sletting av markøren som et objekt fordi lukking av den ikke nødvendigvis frigjør minnet knyttet til det.

Definisjonen av en markør kan variere litt på tvers av implementeringer. Noen ganger må for eksempel en utvikler eksplisitt frigjøre minnet som er tildelt for en markør. Etter slipp markøren det tilhørende minnet frigjøres også. Dette gjør det mulig å gjenbruke navnet hans. I andre implementeringer når lukker markøren frigjøring av minne skjer implisitt. Umiddelbart etter gjenoppretting blir den tilgjengelig for andre operasjoner: åpne en annen markør etc.

I noen tilfeller er det uunngåelig å bruke en markør. Men hvis mulig, bør dette unngås og arbeid med standard databehandlingskommandoer: SELECT, UPDATE, INSERT, DELETE. I tillegg til at markørene ikke tillater modifikasjonsoperasjoner på hele datavolumet, er hastigheten for å utføre databehandlingsoperasjoner ved hjelp av en markør merkbart lavere enn for standard betyr SQL.

Implementering av markører i MS SQL Server-miljø

SQL Server støtter tre typer markører:

  • SQL-pekere brukes primært innenfor triggere, lagrede prosedyrer og skript;
  • servermarkører opererer på serveren og implementerer applikafor ODBC, OLE DB, DB_Library;
  • Klientmarkører er implementert på selve klienten. De henter hele resultatsettet med rader fra serveren og lagrer det lokalt, noe som øker hastigheten på databehandlingen ved å redusere bortkastet tid brukt på nettverksoperasjoner.

Ulike typer flerbrukerapplikasjoner krever ulike typer parallell tilgang til data. Noen applikasjoner krever umiddelbar tilgang til informasjon om endringer i databasen. Dette er typisk for billettbestillingssystemer. I andre tilfeller, som for eksempel statistiske rapporteringssystemer, er datastabilitet viktig fordi hvis den stadig endres, vil ikke programmer kunne vise informasjon effektivt. Ulike applikasjoner trenger forskjellige implementeringer av markører.

I SQL Server varierer markørtyper i egenskapene de gir. Markørtypen bestemmes på tidspunktet for opprettelsen og kan ikke endres. Noen typer markører kan oppdage endringer gjort av andre brukere i rader som er inkludert i resultatsettet. SQL Server sporer imidlertid bare endringer i slike rader mens raden åpnes og tillater ikke endringer når raden allerede er lest.

Markørene er delt inn i to kategorier: sekvensiell og rullbar. Påfølgende lar deg velge data i bare én retning - fra begynnelse til slutt. Rullebare markører gi større handlingsfrihet - det er mulig å bevege seg i begge retninger og hoppe til en vilkårlig rad av markørens resultatsett Hvis programmet er i stand til å modifisere dataene som markøren peker på, kalles det scrollable og modifiable. Når vi snakker om markører, bør vi ikke glemme transaksjonsisolering. Når en bruker endrer en post, leser en annen den ved hjelp av sin egen markør, og dessuten kan han endre den samme posten, noe som gjør det nødvendig å opprettholde dataintegriteten.

SQL Server støtter statisk, dynamisk, sekvensiell og styres av et sett med nøkler.

I ordningen med statisk markør informasjon leses fra databasen én gang og lagres som et øyeblikksbilde (som på et tidspunkt), slik at endringer som er gjort i databasen av en annen bruker ikke er synlige. En stund åpne markøren serveren setter en lås på alle rader som er inkludert i hele resultatsettet. Statisk markør endres ikke etter opprettelsen og viser alltid datasettet som eksisterte på tidspunktet for åpningen.

Hvis andre brukere endrer dataene som er inkludert i markøren i kildetabellen, vil dette ikke påvirke statisk markør.

I statisk markør Det er ikke mulig å gjøre endringer, så det åpnes alltid i skrivebeskyttet modus.

Dynamisk markør opprettholder data i en «live»-tilstand, men dette krever nettverks- og programvareressurser. Ved hjelp av dynamiske markører en fullstendig kopi av kildedataene opprettes ikke, men et dynamisk utvalg utføres fra kildetabellene kun når brukeren får tilgang til visse data. Under hentingen låser serveren radene, og eventuelle endringer brukeren gjør i hele resultatsettet til markøren vil være synlig i markøren. Men hvis en annen bruker har gjort endringer etter at markøren har hentet dataene, vil de ikke reflekteres i markøren.

Markøren styres av et sett med taster, er midt mellom disse ytterpunktene. Registreringer identifiseres ved prøvetaking, og dermed spores endringer. Denne typen markør er nyttig når du implementerer rulling tilbake - da er ikke tillegg og slettinger av rader synlige før informasjonen er oppdatert og driveren velger ny verson poster, hvis det er gjort endringer i dem.

Sekvensielle markører har ikke lov til å hente data i motsatt retning. Brukeren kan bare velge rader fra begynnelsen til slutten av markøren. Seriell markør lagrer ikke et sett med alle rader. De leses fra databasen så snart de er valgt i markøren, noe som gjør at alle endringer gjort av brukere i databasen kan reflekteres dynamisk ved hjelp av INSERT, UPDATE, DELETE kommandoer. Markøren viser den nyeste tilstanden til dataene.

Statiske markører gi en stabil oversikt over dataene. De er gode for informasjons-"lager"-systemer: applikasjoner for rapporteringssystemer eller for statistiske og analytiske formål. I tillegg, statisk markør takler bedre enn andre sampling av store datamengder. I motsetning til dette krever elektroniske kjøps- eller billettbestillingssystemer dynamisk oppfatning av oppdatert informasjon etter hvert som endringer gjøres. I slike tilfeller brukes det dynamisk markør. I disse applikasjonene er mengden data som overføres vanligvis liten og tilgang på radnivå (individuell post). Gruppetilgang er svært sjelden.

Markørhåndtering i MS SQL Server-miljø

Markørkontroll implementert ved å utføre følgende kommandoer:

  • ERKLÆRE - skapelse eller markørerklæring;
  • ÅPEN - åpningsmarkøren, dvs. fylle den med data;
  • HENT valg fra markøren og endre datarader ved å bruke markøren;
  • LUKK - lukker markøren;
  • AVDELING – frigjør markøren, dvs. sletter markøren som et objekt.

Markørerklæring

SQL-standarden gir følgende kommando for å lage en markør:

Bruk av INSENSITIVE nøkkelordet vil skape statisk markør. Dataendringer er ikke tillatt, i tillegg vises ikke endringer gjort av andre brukere. Hvis nøkkelordet INSENSITIVE mangler, a dynamisk markør.

Når du spesifiserer SCROLL nøkkelordet, kan den opprettede markøren rulles i alle retninger, slik at du kan bruke valgkommandoer. Hvis dette argumentet utelates, vil markøren være konsistent, dvs. visningen vil bare være mulig i én retning - fra begynnelse til slutt.

SELECT-setningen spesifiserer kroppen til SELECT-forespørselen, som bestemmer det resulterende settet med rader for markøren.

Å spesifisere FOR READ_ONLY oppretter en skrivebeskyttet markør og tillater ingen endringer i dataene. Det skiller seg fra statisk, selv om sistnevnte heller ikke tillater at data endres. Kan deklareres som en skrivebeskyttet markør dynamisk markør, som vil tillate at endringer gjort av en annen bruker vises.

Å lage en markør med et FOR UPDATE-argument lar deg utføre i markøren dataendring enten i de angitte kolonnene eller, i fravær av argumentet OF kolonnenavn, i alle kolonner.

I MS SQL Server-miljøet godtas følgende syntaks for kommandoen for markøroppretting:

<создание_курсора>::= DECLARE cursor_name CURSOR FOR SELECT_statement ]]

Bruk av nøkkelordet LOCAL vil opprette en lokal markør som bare er synlig innenfor rammen av pakken, utløseren, lagret prosedyre eller tilpasset funksjon. Når en pakke, trigger, prosedyre eller funksjon avsluttes, blir markøren implisitt ødelagt. For å sende innholdet til markøren utenfor konstruksjonen som opprettet den, må du tilordne et OUTPUT-argument til parameteren.

Hvis nøkkelordet GLOBAL er spesifisert, opprettes en global markør; den eksisterer til gjeldende tilkobling er lukket.

Ved å spesifisere FORWARD_ONLY opprettes seriell markør; Data kan bare samples i retning fra første rad til siste.

Spesifisering av SCROLL oppretter rullbar markør; Data kan nås i hvilken som helst rekkefølge og i alle retninger.

Ved å spesifisere STATIC opprettes statisk markør.

Ved å spesifisere KEYSET opprettes en nøkkelmarkør.

Spesifisering av DYNAMIC oppretter dynamisk markør.

Hvis du spesifiserer FAST_FORWARD-argumentet for en READ_ONLY-markør, vil den opprettede markøren bli optimalisert for rask tilgang til dataene. Dette argumentet kan ikke brukes sammen med argumentene FORWARD_ONLY eller OPTIMISTIC.

En markør opprettet med OPTIMISTIC-argumentet forhindrer endring eller sletting av rader som ble endret etter åpne markøren.

Ved å spesifisere TYPE_WARNING-argumentet vil serveren informere brukeren om en implisitt endring av markørtypen hvis den er inkompatibel med SELECT-spørringen.

Åpne markøren

Til åpne markøren og fyll den med data fra SELECT-spørringen som ble spesifisert når du opprettet markøren, bruk følgende kommando:

Etter åpne markøren Den tilknyttede SELECT-setningen utføres, hvis utdata lagres i flernivåminne.

Henter data fra en markør

Rett etter åpne markøren du kan velge innholdet (resultatet av å utføre den tilsvarende spørringen) ved å bruke følgende kommando:

Hvis du spesifiserer FIRST, returneres den aller første raden i markørens komplette resultatsett, som blir gjeldende rad.

Ved å spesifisere LAST returnerer du den nyeste raden i markøren. Det blir også gjeldende linje.

Hvis du spesifiserer NEXT, returneres raden umiddelbart etter den gjeldende i hele resultatsettet. Nå blir det aktuelt. Som standard bruker FETCH-kommandoen denne metoden for å hente rader.

Nøkkelordet PRIOR returnerer raden før det gjeldende. Den blir aktuell.

Argument ABSOLUTT (line_number | @line_number_variable) returnerer en rad med dets absolutte ordenstall i markørens komplette resultatsett. Linjenummeret kan angis ved hjelp av en konstant eller som navnet på en variabel der linjenummeret er lagret. Variabelen må være en heltallsdatatype. Både positive og negative verdier er angitt. Når du spesifiserer en positiv verdi, telles strengen fra begynnelsen av settet, mens en negativ verdi telles fra slutten. Den valgte linjen blir gjeldende linje. Hvis en nullverdi er spesifisert, returneres ingen rad.

Argument RELATIV (antall rader | @variabelt antall rader) returnerer linjen som er det angitte antallet linjer etter den gjeldende. Hvis du spesifiserer et negativt antall rader, vil raden som er det angitte antallet rader før den gjeldende returneres. Hvis du spesifiserer en nullverdi, returneres gjeldende rad. Den returnerte raden blir gjeldende rad.

Til åpne global markør, må du spesifisere GLOBAL nøkkelordet før navnet. Markørnavnet kan også angis ved hjelp av en variabel.

I design INTO @variabelnavn [,...n] en liste over variabler er spesifisert der de tilsvarende kolonneverdiene i den returnerte raden vil bli lagret. Rekkefølgen for å spesifisere variabler må samsvare med rekkefølgen på kolonnene i markøren, og datatypen til variabelen må samsvare med datatypen i markørkolonnen. Hvis INTO-konstruksjonen ikke er spesifisert, vil oppførselen til FETCH-kommandoen ligne oppførselen til SELECT-kommandoen - dataene vises på skjermen.

Endring og sletting av data

For å gjøre endringer ved hjelp av en markør, må du gi en UPDATE-kommando i følgende format:

Flere kolonner i gjeldende markørrad kan endres i én operasjon, men alle må tilhøre samme tabell.

For å slette data ved hjelp av en markør, bruk DELETE-kommandoen i følgende format:

Som et resultat vil linjesettstrømmen i markøren bli slettet.

Lukker markøren

Etter lukking blir markøren utilgjengelig for programbrukere. Når den er lukket, fjernes alle låser som er installert under driften. Lukking kan bare brukes på åpne markører. Stengt men ikke frigjort markøren kan åpnes igjen. Det er ikke tillatt å lukke en uåpnet markør.

Slipp markøren

Lukker markøren frigjør ikke nødvendigvis minnet knyttet til det. Noen implementeringer må eksplisitt deallokere den ved å bruke DEALLOCATE-setningen. Etter slipp markøren Minne er også frigjort, noe som gjør det mulig å gjenbruke markørnavnet.

For å kontrollere om slutten av markøren er nådd, anbefales det å bruke funksjonen: @@FETCH_STATUS

@@FETCH_STATUS-funksjonen returnerer:

0 hvis hentingen var vellykket;

1 hvis hentingen mislyktes på grunn av et forsøk på å hente en linje utenfor markøren;

2 hvis hentingen mislyktes på grunn av et forsøk på å få tilgang til en slettet eller endret rad.

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" DECLARE klient_cursor CURSOR LOCAL FOR SELECT Client Code, Company, Etternavn FRA Client WHERE City="Moscow" BESTILLE ETTER Firma, Etternavn OPEN klient_cursor HENT NESTE FRA klient_cursor INTO @id_kl, @firm, @fam MENS @@FETCH_STATUS =0 BEGIN SELECT @message="Client "+@fam+ "Company "+ @firm PRINT @message SELECT @message="Produktnavn Kjøpsdato Kostnad" SKRIV UT @message DECLARE tovar_cursor CURSOR FOR SELECT Product.Name, Transaction.Date, Product .Pris* Transaksjon.Antall SOM kostnad FRA Produkt INDRE BLI MEDLEM Transaksjon PÅ Produkt. Produktkode=Transaksjon.Produktkode HVOR Transaksjon.Kundekode=@id_kl ÅPNE tovar_cursor FETCH NEXT FROM tovar_cursor INTO @nam, @d, @p IF @@FETCH_STATUS<>0 SKRIV UT "Ingen kjøp" MENS @@FETCH_STATUS=0 BEGIN SELECT @message=" "+@nam+" "+ CAST(@d AS CHAR(12))+" "+ CAST(@p AS CHAR(6)) PRINT @message SET @s=@s+@p FETCH NEXT FROM tovar_cursor INTO @nam, @d, @p END CLOSE tovar_cursor DEALLOCATE tovar_cursor SELECT @message="Total cost "+ CAST(@s AS CHAR(6)) PRINT @message -- flytt til neste klient-- FETCH NEXT FROM klient_cursor INTO @id_kl, @firm, @fam END CLOSE klient_cursor DEALLOCATE klient_cursor Eksempel 13.6. Markør for å vise en liste over varer kjøpt av kunder fra Moskva og deres totale kostnader.

Eksempel 13.7. Utvikle en rullebar markør for klienter fra Moskva. Hvis telefonnummeret begynner med 1, slett klienten med det nummeret og bytt ut det første sifferet i telefonnummeret med 4 i den første markøren.

DECLARE @firm VARCHAR(50), @fam VARCHAR(50), @tel VARCHAR(8), @message VARCHAR(80) SKRIV UT "Liste over klienter" DECLARE klient_cursor CURSOR GLOBAL RULLETAST FOR VELG Firma, Etternavn, Telefon FRA klient HVOR By ="Moscow" BESTILLE ETTER Firma, Etternavn FOR OPPDATERING ÅPNE klient_cursor HENT NESTE FRA klient_cursor INTO @firm, @fam, @tel MENS @@FETCH_STATUS=0 BEGIN SELECT @message="Client "+@fam+ " Company "+ @firm " Telefon "+ @tel SKRIV UT @melding -- hvis telefonnummeret begynner med 1, -- slett klienten med det nummeret HVIS @tel LIKE '1%' SLETT klient HVOR AKTUELL AV klient_cursor ANDRE -- gå til neste klient FETCH NEXT FROM klient_cursor INTO @firm, @fam, @tel END FETCH ABSOLUTE 1 FROM klient_cursor INTO @firm, @fam, @tel -- i den første oppføringen, erstatt det første sifferet i telefonnummeret med 4 UPDATE Client SET Phone ='4' + RIGHT(@ tel,LEN(@tel)-1)) WHERE CURRENT OF klient_cursor SELECT @message="Client "+@fam+" Firm "+ @firm "Phone "+ @tel PRINT @message CLOSE klient_cursor DEALLOCATE klient_cursor Eksempel 13.7. Rullebar markør for klienter fra Moskva.

Eksempel 13.8. Bruk markøren som en utdataparameter for prosedyren. Prosedyren returnerer et datasett - en liste over produkter.

Å kalle frem prosedyren og skrive ut data fra utdatamarkøren utføres som følger:

DECLARE @my_cur CURSOR DECLARE @n VARCHAR(20) EXEC my_proc @cur=@my_cur OUTPUT FETCH NEXT FROM @my_cur INTO @n VELG @n MENS (@@FETCH_STATUS=0) BEGYNNER HETTING NESTE FRA @my_cur INTO @n SELECT SLUTT LUKK @my_cur DEALLOCATE @my_cur


Markøren er en lenke til det kontekstuelle minneområdet. I noen implementeringer av SQL-programmeringsspråket (Oracle, Microsoft SQL Server) - resultatsettet oppnådd ved utføring av en spørring og den tilhørende gjeldende postpekeren. Jeg vil si at markøren er virtuelt bord som er et alternativt datalager. I dette tilfellet lar markøren deg få tilgang til dataene som om de var dataene til en vanlig matrise.
Markører brukes i lagrede prosedyrer. Nok teori, la oss se på et eksempel:
Vi har en database (databasen er litt dårlig, dette er en av mine laboratoriearbeid, men databaselæreren vår insisterte på en slik struktur)
/*Bank informasjon*/
OPPRETT TABELL "bank" (

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


PRIMÆR NØKKEL («BankId»)

)ENGINE=InnoDB
TEGNSETT "utf8" SAMLER "utf8_bin" ;
/*data om innskudd */
OPPRETT TABELL `bankdistribusjon` (
`BankId` INTEGER (11) IKKE NULL ,
`Persent` INTEGER (11) DEFAULT NULL ,
`ContributeAmount` DESIMAL (10,0) IKKE NULL ,
`ClientId` INTEGER (11) IKKE NULL ,
PRIMARY KEY(`BankId`, `ClientId`),
NØKKEL `BankId` (`BankId`),
NØKKEL `ClientId` (`ClientId`),
BEGRENSNING `bankdistribution_fk` FOREIGN KEY (`BankId`) REFERANSER `bank` (`BankId`),
BEGRENSNING `bankdistribution_fk1` FOREIGN KEY (`ClientId`) REFERANSER `client` (`ClientId`)
)ENGINE=InnoDB
/*data om investorer*/
OPPRETT TABELL `klient` (
`ClientId` INTEGER (3) IKKE NULL AUTO_INCREMENT,
`CreditCardId` BIGINT(10) NOT NULL ,
`Etternavn` VARCHAR (50) COLLATE utf8_bin IKKE NULL STANDARD "" ,
`Navn` VARCHAR (50) COLLATE utf8_bin IKKE NULL STANDARD "" ,
`FirstName` VARCHAR (50) COLLATE utf8_bin IKKE NULL STANDARD "" ,
`Telefon` VARCHAR (50) COLLATE utf8_bin IKKE NULL STANDARD "" ,
`Adresse` VARCHAR (50) COLLATE utf8_bin IKKE NULL STANDARD "" ,
`SafeId` INTEGER (5) IKKE NULL ,
PRIMARY KEY(`ClientId`, `CreditCardId`),
NØKKEL `ClientId` (`ClientId`)

)ENGINE=InnoDB
AUTO_INCREMENT=11 TEGNSETT "utf8" SAMLER "utf8_bin"

La oss si at vi må motta hver bank etter tur og utføre noen handlinger med den. Følgende spørring kan hjelpe oss med dette

Velg `bank`.* FRA `bank` LIMIT NUMBER OF THE_RECORD_WE NEED,1
. Ved å bruke LIMIT WE NEED_RECORD NUMBER, 1, trekker vi ut hver post i en løkke fra banktabellen og utfører handlingene vi trenger med den, samtidig som vi øker verdien av WE NEED_RECORD NUMBER med 1. Nå vil vi gjøre det samme, men ved å bruke en markøren
Begynne
/* variabler der vi trekker ut data */
Erklær vBankId heltall ;
Erklær vBanknavn VARCHAR(50);
Erklær vAddress VARCHAR(50);
Erklær vPhone VARCHAR (50);
/* hadler variabel - a*/
Erklære ferdig heltall standard 0;
/*Markørerklæring*/
Deklarer BankCursor Cursor for Velg `bank`.`BankId`,`bank`.`BankName`,`bank`.`Adresse`,`bank`.`Telefon`, FROM `bank` hvor 1;
/*HANDLER-formål, som vil bli forklart nedenfor*/
ERKLÆR FORTSETT HANDLER FOR SQLSTATE "02000" SET done=1;
/* åpne markøren */
Åpne BankCursor;
/*hente data*/
Mens ferdig = 0 GJØR

vi tar de handlingene vi trenger
AVSLUTT MED ;
/*lukker markøren*/
Lukk BankCursor;
SLUTT ;

* Denne kildekoden ble uthevet med Source Code Highlighter.

Feil: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)

Melding: Ingen data – null rader hentet, valgt eller behandlet

SQLSTATE: 02000 utløses når slutten av markøren nås, eller når valg eller oppdatering returnerer en tom streng.

Den neste linjen erklærte vi markøren DECLARE cursor_name CURSOR FOR select_statement;
Åpne markøren Åpne cursor_name;
Så, til vi kommer til slutten av markøren (MENS ferdig = 0 DO), trekker vi ut dataene og behandler dem.
Du må lukke markøren før du avslutter den lagrede prosedyren. Lukk cursor_name;

Det virker ikke komplisert. Men det er mange fallgruver knyttet til SQLSTATE "02000".

Mens ferdig = 0 GJØR
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;

Velg (ContributeAmount) INTO vContributeAmountSUM FRA bankdistribution hvor BankId = vBankId limit 1;
vi gjør noen handlinger
SLUT MED ;

* Denne kildekoden ble uthevet med Source Code Highlighter.


Alt er fint og korrekt fra et syntakssynspunkt. Men fra et logisk synspunkt, nei. Det kan skje at innskytere ikke har åpnet konto i en eller annen bank, da for Velg (ContributeAmount) INTO vContributeAmountSUM FRA bankdistribusjon hvor BankId = vBankId limit 1; SQLSTATE: 02000 vil utløses, den ferdige variabelen settes til 1, og mens loop avsluttes tidligere enn vi forventet. Dette kan unngås ved å gjøre følgende
Mens ferdig = 0 GJØR
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* trekke ut beløpet for bankens innskudd */


if (vContributeAmountSUM > 0) da
/* trekke ut beløpet for bankens innskudd */

slutt om ;
vi gjør noen handlinger
SLUT MED ;

* Denne kildekoden ble uthevet med Source Code Highlighter.


Med den første forespørselen sjekket vi om det er bidrag (hvis det ikke er noen, så vContributeAmountSUM == 0) og bare hvis det er noen, henter vi dataene.

La oss nå si at vi må fjerne det totale beløpet på kontoer i forskjellige banker for hver klient
Angi ClientSummCursor Cursor for Velg sum

Angi ClientSummCursor Cursor for Select sum (`bankdistribution`.`ContributeAmount`), `bankdistribution`.`ClientId` FROM `bankdistribution` Inner Join client on (client.ClientId = bankdistribution.`ClientId`) hvor 1 gruppe etter `bankdistribution`. `ClientId`;

Åpne ClientSummCursor;
Mens ferdig = 0 GJØR
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* trekke ut beløpet for bankens innskudd */
Velg Count(ContributeAmount) INTO vContributeAmountSUM FRA bankdistribution hvor BankId = vBankId limit 1;
/* sjekk om det virkelig er innskudd i denne banken */
if (vContributeAmountSUM > 0) da
/* trekke ut beløpet for bankens innskudd */
Velg ContributeAmount INTO vContributeAmountSUM FRA bankdistribution hvor BankId = vBankId limit 1;
slutt om ;


vi gjør noen handlinger.
SLUT MED ;

* Denne kildekoden ble uthevet med Source Code Highlighter.

Samme situasjon kan oppstå når dataene i ClientSummCursor-markøren slutter tidligere enn dataene i BankCursor, SQLSTATE: 02000 utløses, done-variabelen settes til 1, og while-løkken slutter tidligere enn vi forventet. Dette kan unngås ved å gjøre følgende

Åpne ClientSummCursor;
Mens ferdig = 0 GJØR
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* trekke ut beløpet for bankens innskudd */
Velg Count(ContributeAmount) INTO vContributeAmountSUM FRA bankdistribution hvor BankId = vBankId limit 1;
/* sjekk om det virkelig er innskudd i denne banken */
if (vContributeAmountSUM > 0) da
/* trekke ut beløpet for bankens innskudd */
Velg ContributeAmount INTO vContributeAmountSUM FRA bankdistribution hvor BankId = vBankId limit 1;
slutt om ;
/* før du trekker ut data fra den andre markøren, husk sqlstate-tilstanden */
SET old_status = ferdig;
/* trekke ut dataene vi trenger */
FETCH ClientSummCursor INTO vSum,vClientId;
/* sjekk om dataene ble hentet og om sqlstate 0200 mislyktes */
hvis (ferdig = 0) da
vi gjør noen handlinger.
slutt om ;
/* før slutten av mens, gjenopprett verdien av den ferdige variabelen */
satt ferdig = gammel_status;
SLUT MED ;

* Denne kildekoden ble uthevet med Source Code Highlighter.

Takk til alle som har lest så langt, jeg håper dette vil være nyttig for noen.

DET GJELDER FOR: SQL Server (siden 2008) Base SQL-data Azure SQL Data WarehouseParallell Data Warehouse

Definerer attributter til en Transact-SQL-servermarkør, for eksempel visningsegenskaper og spørringen som brukes til å bygge resultatsettet som markøren opererer på. DECLARE CURSOR-setningen støtter både ISO-standardsyntaks og syntaks som bruker Transact-SQL-språkutvidelsessettet.

ISO syntaks DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR FOR select_statement [FOR (LES BARE | OPPDATERING [OF kolonnenavn [,...n]])] [;] Transact-SQL utvidet syntaks DEKLARER cursor_name CURSOR [ LOKAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATISK | NØKKELSETT | DYNAMISK | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ] FOR select_statement [ FOR UPDATE [ OF column_name [ ,...n ] ] ] [;]

cursor_name
cursor_name

UFØLSOM
tempdb; dermed reflekteres ikke endringer i de underliggende tabellene i dataene som returneres av denne markørens valg, og denne markøren kan ikke endres. Når du bruker ISO-syntaks, med mindre alternativet INSENSITIVE er spesifisert, vises forpliktede oppdateringer og slettinger gjort til basistabellene i påfølgende valg.

RULL
Indikerer at alle samplingsalternativer er tilgjengelige (FØRSTE, SISTE, FORRIGE, NESTE, RELATIVE, ABSOLUTT). Hvis ISO DECLARE CURSOR-setningen ikke spesifiserer et SCROLL-alternativ, støttes kun alternativet NEXT-henting. SCROLL-alternativet kan ikke spesifiseres med FAST_FORWARD-alternativet.

select_statement
Standard SELECT-setning, som definerer resultatsettet til markøren. Nøkkelord FOR Browse og INTO er ikke tillatt select_statement markørerklæring.

select_statement konflikt med en markør av den forespurte typen.

LES BARE

Oppdater ]
kolonnenavn [, .. .n] er spesifisert, tillater kun de oppførte kolonnene endringer. Hvis UPDATE-setningen brukes uten en liste over kolonner, er oppdateringen mulig for alle kolonner.

cursor_name
Transact-SQL-navnet til den spesifikke servermarkøren. cursor_name må følge reglene for identifikatorer.

LOKAL
Indikerer at markøren er lokal for pakken, den lagrede prosedyren eller triggeren den ble opprettet i. Markørnavnet er kun gyldig innenfor dette området. En markør kan refereres av lokale pakkevariabler, lagrede prosedyrer, triggere eller utdataparameteren til en lagret prosedyre. OUTPUT-parameteren brukes til å sende en lokal markør til anropspakken, lagret prosedyre eller trigger, som deretter kan tilordne parameteren til en markørvariabel for påfølgende tilgang til markøren etter at den lagrede prosedyren er fullført. Markøren frigjøres implisitt når batchen, den lagrede prosedyren eller utløseren fullfører kjøringen, med mindre markøren ble sendt til OUTPUT-parameteren. Hvis markøren ble sendt til OUTPUT-parameteren, frigjøres markøren når alle variabler som refererer til den er frigjort eller når skopet avsluttes.

GLOBAL
Indikerer at markøren er global for forbindelsen. Markørnavnet kan brukes av enhver lagret prosedyre eller pakke som kjører på tilkoblingen. Markøren frigjøres implisitt bare hvis forbindelsen brytes.

FORWARD_ONLY
Angir at markøren kun kan vises fra første linje til siste. Bare FETCH NEXT-hentingsalternativet støttes. Hvis FORWARD_ONLY er spesifisert uten nøkkelordene STATIC, KEYSET eller DYNAMIC, oppfører markøren seg som en DYNAMISK markør. Hvis verken FORWARD_ONLY-argumentet eller SCROLL-argumentet er spesifisert, er standarden FORWARD_ONLY-argumentet med mindre nøkkelordene STATIC, KEYSET eller DYNAMIC er til stede. STATIC-, KEYSET- og DYNAMIC-markørene har standardverdien SCROLL. I motsetning til database-API-er som ODBC og ADO, støttes FORWARD_ONLY-modus av følgende Transact-SQL-markører: STATIC, KEYSET og DYNAMIC.

STATISK
Definerer en markør som lager en midlertidig kopi av data for bruk av markøren. Alle spørringer til markøren får tilgang til den spesifiserte midlertidige tabellen i tempdb; dermed reflekteres ikke endringer i de underliggende tabellene i dataene som returneres av denne markørens valg, og denne markøren kan ikke endres.

NØKKELSETT
Indikerer at medlemskapet eller rekkefølgen til radene i markøren er uendret når den åpnes. Et sett med nøkler som unikt identifiserer rader er innebygd i tabellen tempdb kalt nøkler.

Endringer i ikke-nøkkelverdier i basistabeller gjort av markørens eier eller begått av andre brukere vises når markørens eier ser det. Endringer gjort av andre brukere reflekteres ikke (endringer kan ikke gjøres ved å bruke Transact-SQL-servermarkøren). Hvis en rad slettes, vil forsøk på å hente rader returnere @@FETCH_STATUS -2. Oppdateringer av nøkkelverdier på grunn av markørgrenser ligner på å slette en gammel rad og deretter sette den inn ny linje. Raden med de nye verdiene er ikke synlig og prøver å hente raden med de gamle verdiene returnerer @@FETCH_STATUS -2. Oppdateringer er synlige umiddelbart hvis de gjøres gjennom markøren ved å bruke WHERE CURRENT OF-leddet.

DYNAMISK
Definerer en markør som viser alle dataendringer som er gjort på rader i resultatsettet mens du viser denne markøren. Dataverdier, rekkefølge og radmedlemskap i hvert utvalg kan variere. Valgalternativet ABSOLUTT støttes ikke av dynamiske markører.

FAST_FORWARD
Indikerer en FORWARD_ONLY, READ_ONLY markør som har ytelsesoptimalisering aktivert. Alternativet FAST_FORWARD kan ikke spesifiseres med alternativene SCROLL eller FOR_UPDATE.

READ_ONLY
Forhindrer endringer som gjøres med denne markøren. WHERE CURRENT OF-leddet kan ikke referere til en markør i en UPDATE- eller DELETE-setning. Dette alternativet har forrang over standard markøroppdateringsfunksjon.

SCROLL_LOCKS
Indikerer at posisjonerte oppdateringer eller slettinger gjort ved hjelp av markøren garantert vil lykkes. SQL Server låser rader når de leses inn i markøren for å sikre at disse radene er tilgjengelige for påfølgende endringer. Alternativet SCROLL_LOCKS kan ikke spesifiseres med alternativet FAST_FORWARD eller STATIC.

OPTIMISTISK
Spesifiserer at posisjonerte oppdateringer eller slettinger gjort med markøren vil mislykkes hvis raden har blitt oppdatert siden den ble lest inn i markøren. SQL Server låser ikke rader når de leses inn i markøren. Sammenligninger brukes i stedet tidsstempel kolonneverdier eller kontrollsummer hvis tabellen ikke har tidsstempel kolonne for å avgjøre om raden har endret seg siden den ble lest inn i markøren. Hvis raden har blitt endret, vil forsøk på en posisjonert oppdatering eller sletting mislykkes. Alternativet OPTIMISTISK kan ikke spesifiseres med alternativet FAST_FORWARD.

TYPE_WARNING
Spesifiserer at en advarsel vil bli sendt til klienten hvis markøren implisitt konverteres fra en forespurt type til en annen.

select_statement
En standard SELECT-setning som spesifiserer resultatsettet til en markør. Nøkkelordene COMPUTE, COMPUTE BY, FOR Browse og INTO er ikke tillatt i select_statement markørerklæring.

SQL Server konverterer implisitt markøren til en annen type hvis klausulene i select_statement konflikt med en markør av den forespurte typen. For mer informasjon, se Implisitte markørkonverteringer.

FOR OPPDATERING]
Definerer kolonnene i markøren som skal oppdateres. Hvis OF kolonnenavn [, ... n] er oppgitt, tillater bare de oppførte kolonnene endringer. Hvis UPDATE-setningen brukes uten en kolonneliste, er oppdateringen mulig for alle kolonner med mindre samtidighetsalternativet READ_ONLY er spesifisert.

DECLARE CURSOR-setningen definerer attributter til en Transact-SQL-servermarkør, for eksempel visningsegenskaper og spørringen som brukes til å bygge resultatsettet som markøren opererer på. OPEN-setningen fyller ut resultatsettet, og FETCH-setningen returnerer en rad fra den. CLOSE-setningen sletter gjeldende resultatsett knyttet til markøren. DEALLOCATE-setningen frigjør ressurser som brukes av markøren.

Den første formen av DECLARE CURSOR-setningen bruker ISO-syntaks for å spesifisere markørparametere. Den andre formen av DECLARE CURSOR-setningen bruker utvidelser til Transact-SQL-språket som lar deg definere markører ved å bruke de samme typene som brukes i markørfunksjonene til database-API-er som ODBC og ADO.

Disse to formene kan ikke blandes. Hvis du spesifiserer SCROLL eller utelater nøkkelord før CURSOR-nøkkelordet, kan du ikke bruke nøkkelord mellom CURSOR og også for select_statement søkeord. Når du spesifiserer nøkkelord mellom CURSOR, samt for select_statement nøkkelord, kan du ikke spesifisere SCROLL eller INSENSITIVE før CURSOR nøkkelordet.

Hvis du bruker Transact-SQL-syntaks for DECLARE CURSOR-setningen og ikke spesifiserer READ_ONLY, OPTIMISTIC eller SCROLL_LOCKS alternativene, antas følgende standardverdi.

    Hvis SELECT-setningen ikke støtter oppdateringer (eller har utilstrekkelige tillatelser, eller har tilgang til eksterne tabeller som ikke støtter oppdateringer osv.), settes markøren til READ_ONLY.

    STATIC- og FAST_FORWARD-markørene er som standard READ_ONLY.

    DYNAMIC- og KEYSET-markørene er som standard OPTIMISTISK.

Markører kan bare refereres til av andre Transact-SQL-setninger. Database API-funksjoner kan ikke referere til markører. For eksempel, når en markør er deklarert, kan ikke OLE DB-, ODBC- eller ADO-funksjoner og -metoder referere til navnet. Markørrader kan ikke velges ved å bruke de tilsvarende API-funksjonene og -metodene; For dette formålet må du bruke Transact-SQL FETCH-setninger.

Følgende lagrede prosedyrer kan brukes til å definere egenskapene til en markør etter at den har blitt deklarert.

Variabler kan brukes som en del select_statement, der markøren er deklarert. Verdiene til markørvariablene endres ikke etter at de er deklarert.

Som standard gis DECLARE CURSOR-tillatelser til alle brukere som har SELECT-tillatelse på visningene, tabellene og kolonnene som brukes av markøren.

Du kan ikke bruke markører eller utløsere på en tabell med en klynget kolonnelagerindeks. Denne begrensningen gjelder ikke for ikke-klyngede indekser; Du kan bruke markører og utløsere på en tabell med en ikke-klynget kolonnelagerindeks.

A. Bruke en enkel markør og syntaks

Resultatsettet som ble opprettet når du åpner denne markøren inkluderer alle rader og kolonner i tabellen. Denne markøren kan oppdateres, alle oppdateringer og slettinger er representert i utvalget for denne markøren. FETCH``NEXT hentes bare fordi SCROLL-parameteren ikke ble spesifisert.

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

B. Bruke nestede markører for å vise en rapport

Følgende eksempel bruker nestede markører for å vise en kompleks rapport. En intern markør er deklarert for hver leverandør.

STILL ANTALL PÅ ; DECLARE @vendor_id int , @vendor_name nvarchar ( 50 ), @message varchar ( 80 ), @product nvarchar ( 50 ); SKRIVE UT" -------- Rapport om leverandørprodukter --------"; DECLARE vendor_cursor CURSOR FOR 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 WHILE @@FETCH_STATUS = 0 BEGYNN UTSKRIFT " " VELG @message = "----- Produkter fra leverandør: "+ @leverandørnavn SKRIV UT @melding -- Erklære en indre markør basert -- på vendor_id fra den ytre markøren. DECLARE product_cursor CURSOR FOR SELECT v.Name FROM Purchasing.ProductVendor pv, Production.Product v WHERE pv.ProductID = v.ProductID AND pv.VendorID = @vendor_id -- Variabel verdi fra den ytre markøren OPEN product_cursor FETCH NEXT FROM product_cursor INTO @product IF @@FETCH_STATUS<>0 SKRIV UT "<>" WHILE @@FETCH_STATUS = 0 BEGIN SELECT @message = " " + @product PRINT @message FETCH NEXT FROM product_cursor INTO @product END CLOSE product_cursor DEALLOCATE product_cursor -- Hent neste leverandør. FETCH NEXT FROM vendor_cursor INTO @vendor_name, @vendor_name END CLOSE vendor_cursor; DEALLOCATE vendor_cursor;

Det kan godt hende at svaret på en enkel klientforespørsel vil være et utvalg av hundretusenvis av rader, noe som er ufordøyelig for de fleste klienter. I dette tilfellet er løsningen på problemet med interaksjon med klienter å bruke markører som en universell mekanisme for å utveksle data mellom serveren og klienten. Markører arbeider med resultatsettet med data (resultatet av en spørring), og gir brukerne ytterligere databehandlingsmuligheter:

Markører lar deg jobbe med tabellrader ved å spesifisere serienummeret deres i datasettet;

Markører lar deg implementere komplekse datamodifikasjonsoperasjoner, for eksempel når du endrer verdien til en kolonne krever gjentatt tilgang til verdiene til andre kolonner.

Markørens livssyklus:

Opprette en markør: ERKLÆRE<имя курсора>[ INSENSITIV ] [ SCROLL ] MARKØR FOR< SELECT -оператор>FOR (KUN LESE | OPPDATERING)

Her betyr INSENSITIVE nøkkelordet at markøren vil være statisk (et øyeblikksbilde av dataene), mens markøren som standard opprettes dynamisk (henting utføres hver gang raden åpnes). Nøkkelordet SCROLL betyr at markøren kan rulles i alle retninger, ellers opprettes markøren som en "sekvensiell" markør.

Åpningsmarkør:ÅPEN [GLOBAL]<имя курсора>. En markør spesifisert som GLOBAL slettes ikke automatisk når prosedyren eller pakken som den ble kalt opp fra, avsluttes.

Lesningdata : HENT [[ NESTE | FØR | FØRSTE | SISTE | ABSOLUTT n | RELATIVE n ] FRA ] [ GLOBAL ]<имя курсора>[INTO@variabelnavn,...]. SQL Server 2000 lar deg lese bare én rad fra en markør. Det FØRSTE nøkkelordet er å returnere den første raden av markøren; LAST – siste linje i markøren; NESTE – neste linje etter den gjeldende, den returnerte linjen blir den gjeldende; PRIOR – forrige før gjeldende; ABSOLUTE n – returnerer en linje med dets absolutte sekvensnummer i markøren; RELATIVE – n linjer etter den gjeldende. Kolonnedataene vil bli lagret i hver av de spesifiserte variablene i den rekkefølgen de er oppført.

Endre data: utfører en UPDATE-kommando med syntaks designet for arbeid med markører.

Sletter data: utfører en DELETE-kommando med syntaks designet for å fungere med markører.

Lukke markøren: LUKK [GLOBAL]<имя курсора>

Slipp markøren: TILDELE [GLOBAL]<имя курсора>

Et eksempel på bruk av en markør:

DECLARE fo_curs MARKØR STATISK FOR

VELG name_rus from for BESTILLE BY name_rus

DECLARE @name varchar(50)

HENT FØRST FRA fo_curs INTO @navn

WHILE @@FETCH_STATUS=0

HENT NESTE FRA fo_curs INTO @navn

DEALLOCATE fo_curs

2.7. Sikre datasikkerhet og integritet i Microsoft SQL Server. Database ledelse. Roller. Tildeling av rettigheter til brukere (GI, NEKTE, OPPBAKE). Metoder og teknologier for databeskyttelse i SQL Server.

SQL Server sikkerhet og administrasjon. .

Hovedoppgaven til et DBMS er å sikre integriteten og konsistensen til data innenfor det valgte fagområdet. En av faktorene som hindrer systemet i å løse seg denne oppgaven, er handlingene til brukere som ved et uhell eller med vilje prøver å ødelegge datastrukturen eller endre selve dataene. Følgelig må DBMS ikke bare beskyttes mot fysiske feil, men også mot brukere som er utilstrekkelige for oppgavene som implementeres. For å gjøre dette er det nødvendig å designe og koble et sikkerhetssystem til databasen som vil hindre brukere i å utføre handlinger utenfor deres autoritet.

Database ledelse

For å lage en database ved hjelp av TSQL, bruk CREATE DATABASE-kommandoen, men vanligvis brukes egenskapene til SQL Server Management Studio til dette formålet. I SQL server ganske mange databaseoperasjoner er definert: øke (minske) filstørrelser, endre konfigurasjon (ALTER-kommando), legge ved og frakoble, overføre eierskap, endre navn, vise egenskaper og til slutt, sletting (DROP DATABASE).

Som de fleste databaseservere har SQL Server en bruker med fulle administrative rettigheter - dette er Systemadministrator eller "sa". Etter den første serverinstallasjonen er sa-passordet tomt. Brukeren som oppretter en ny database blir automatisk eieren av den ('dbo' - Data Base Owner) På det tidspunktet databasen opprettes, defineres også brukeren "gjest" Dersom brukerkontoen ikke er eksplisitt tilordnet en bruker av en spesifikk database, får brukeren implisitt tilgang med å bruke gjestenavnet gjest.Gjest er vanligvis forbudt.

Brukeren som oppretter et objekt i databasen blir automatisk eieren av det, og ingen, inkludert dbo og sa, kan bruke det objektet før eieren tildeler dem rettigheter til det. Men for at en bruker skal kunne opprette et objekt, må databaseeieren først gi ham de riktige rettighetene.

Rolle lar deg kombinere brukere som utfører de samme funksjonene for å forenkle administrasjonen. Roller kan være innebygd eller tilpasset. Innebygde roller implementeres på servernivå og på databasenivå. Nedenfor er en tabell over innebygde databaseroller:

db_eier. Har alle rettigheter i databasen

Db_accessadmin. Kan legge til eller fjerne brukere

Db_securityadmin. Administrerer alle tillatelser, objekter, roller og brukere

Db_ddladmin. Kan utføre alle DDL-kommandoer unntatt GRANT, DENY, REVOKE

Db_backupoperator. Archiver kan utføre kommandoer. data

db_datareader. Kanskje visning. alle data i en hvilken som helst tabell

db_datawriter. Kanskje en modifikasjon. alle data i enhver tabell

Db_denydatareader. Forbudt utsikt kjærlighet data i noen tabeller

Db_denydatawriter. Forby modifikasjon av data i noen tabeller

Tildeling av rettigheter til brukere. Grunnlaget for SQL Server-sikkerhet er (1) Kontoer(regnskap); (2) brukere; (3) roller; (4) grupper.

Når en bruker kobler til SQL Server, bestemmes handlingene han kan utføre av rettighetene som er gitt til ham som bruker og medlem av en rolle. Rettigheter tildeles av DBMS-administratoren, databaseeieren eller eieren av et spesifikt databaseobjekt. Rettigheter i databasen kan deles inn i tre kategorier: (1) rettigheter til tilgang til databaseobjekter; (2) rettigheter til å utføre TSQL-kommandoer; (3) implisitte rettigheter. Serveren lar deg overføre eierskap fra en bruker til en annen.

Følgende kommandoer brukes til å administrere brukertillatelser for å få tilgang til databaseobjekter:

STIPEND(ALLE |< вид действия >,…}

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

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

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

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

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

tildele rettigheter til brukere, Hvor

ALLE – brukeren får alle mulige tillatelser, ellers spesifiser

<вид действия>– rettigheter til handlinger tilgjengelig for brukeren, nemlig:

SELECT – for visning, for tabellkolonne og for tabell (visning)

INSERT – for å legge til, for tabellen (visningen) som helhet

OPPDATERING – for endring, for en tabellkolonne og for en tabell (visning)

SLETT – for å slette, for tabellen (visningen) som helhet

EXECUTE – for å utføre lagrede prosedyrer

REFERANSER – muligheten til å referere til et spesifisert objekt (inkluder det som en del av en fremmednøkkel).

<имя объекта системы безопасности>– SQL Server-kontoer, Windows-domenebrukere; OFFENTLIG – for alle brukere.

MED TILDELINGSALTERNATIV - lar brukeren som for øyeblikket er tildelt rettigheter, tildele tilgangsrettigheter til objektet til andre brukere.

SOM<имя группы> | <имя роли>– deltakelse av en bruker i en rolle som gis mulighet til å gi rettigheter til andre brukere.

GI UTVALG PÅ forfattere TIL offentligheten

GIV INNSERT, OPPDATERING, SLETT PÅ forfattere TIL Mary, John, Tom

TILLEIE VALG PÅ Plan_Data TIL Regnskap MED TILSKUDSVALG

GI VALG PÅ Plan_Data TIL Jack AS Regnskap

Jack er ikke medlem av regnskapsrollen, men noen i den rollen kan gi tillatelse

BENEKTE(ALLE |< вид действия >,…}

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

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

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

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

tilgangsnektelse brukere til databaseobjekter. CASCADE tilbakekaller rettigheter ikke bare fra gitt bruker, men også for alle som han har gitt rettigheter.

Eksempel (på kommandoforbud TSQL):

NEKT OPPRETT BORD TIL Jack CASCADE

Team OPPHAV brukes til å implisitt nekte tilgang til databaseobjekter. Syntaksen er den samme som DENY-kommandoen. Implisitt nektelse ligner på å nekte tilgang, bortsett fra at det bare gjelder på det nivået det er definert på. Eksempel: Brukeren Jack, som er medlem av GoodUsers-rollen, har fått tilgangsrettigheter til XFiles-tabellen. Hvis REVOKE nektes for GoodUsers-rollen for å få tilgang til denne tabellen, kan Jack fortsatt få tilgang til denne tabellen fordi rettighetene for ham er eksplisitt definert. Hvis du bruker REVOKE personlig for ham, vil han miste retten til å få tilgang til XFiles.

Tillatelser gitt til roller arves av medlemmene deres. Hvis en bruker får tilgang til et objekt gjennom medlemskap i én rolle, men nektes i en annen, løses alltid tilgangskonflikten til fordel for nektelse.

Databeskyttelsesteknologier i MS SQL Server

1. Mekanisme sjekkpunkter– sjekkpunkter som genereres etter ~60 s for å skrive oppdaterte sider til disken (et sjekkpunkt kan tvinges frem av CHECKPOINT-kommandoen).

2. Innebygde og eksterne mekanismer for å sjekke integriteten til databasen (startes automatisk eller, som DBCC-verktøyet - Database Consistency Checker - manuelt).

3. Fysisk duplisering (hvis tillatt) av databasefiler ved bruk av operativsystemet (inkludert mekanismen til speilede harddisker).

4. Sikkerhetskopiering av databaser og transaksjonslogger - ved å skrive en databasedump til en sikkerhetskopienhet (magnetbånd eller harddisk).

5. Replikering – muligheten til å duplisere informasjon ved periodisk (i noen tilfeller synkront) å overføre den fra en SQL-server til en annen.

6. Kryptering av trafikk mellom klient og server, samt kryptering av koder som brukes til å arbeide med databaseobjekter (lagrede prosedyrer, triggere osv.)

1) Konseptet med en markør
Interaktiv SQL skiller ikke mellom spørringer med én rad og flere rader. Innebygd SQL utfører disse spørringene annerledes. Enkeltlinjespørringer returnerer én linje, og vi har allerede dekket dem. Når resultatet av en spørring er mer enn én rad, må innebygd SQL tillate at applikasjonen henter spørringsresultatene rad for rad. Det brukes markører til dette. En markør er en variabel knyttet til en spørring. Verdien er hver rad som samsvarer med søket. I likhet med variabler må markørene deklareres før de kan brukes. I motsetning til visninger, er markørene designet for linje-for-linje-behandling.

2) Markørerklæring

ERKLÆRE [{}] [[NEI] RULL] MARKØR [{UTEN|UTEN} HOLDE] TIL [TIL {LES BARE|OPPDATERING [AV ]}]

3) Nøkkelord
. SENSITIV|INSENSITIV|ASENSITIV– endringer i resultatsettet er synlige | forbudt (fiksert ved hjelp av en kopi av datasettet)|DBMS bestemmer selv om det skal lages en kopi (fungerer som standard).
. UTEN UTEN HOLD– blader åpne | lukker markøren hvis en COMMIT-setning oppstår.
. RULL– [hindrer] å trekke ut resultatrader i tilfeldig rekkefølge.
. KUN FOR LESING– definerer en skrivebeskyttet markør.
. FOR OPPDATERING AV– blokkerer bare de angitte kolonnene fra å oppdatere.

4) Deklarere en markør i SQL Server

ERKLÆRE MARKØR [LOKAL|GLOBAL] [FORWARD_ONLY|RULL] [STATISK|KEYSETT|DYNAMISK|RASK_FRAMOVER] [READ_ONLY|SCROLL_LOCKS|OPTIMISTISK] TIL [FOR OPPDATERING [AV ]]

. STATISK– Definerer en markør som lager en midlertidig kopi av data for bruk av markøren. Alle spørringer mot en markør får tilgang til den spesifiserte midlertidige tabellen i tempdb-databasen, så endringer i basistabellene påvirker ikke dataene som returneres av samples for den markøren, og selve markøren tillater ikke endringer.
. NØKKELSETT– Indikerer at medlemskapet eller rekkefølgen av rader i markøren ikke endres etter at den er åpnet. Et sett med nøkler som unikt identifiserer rader er innebygd i en tabell i tempdb-databasen kalt keyset.
. DYNAMISK– Definerer en markør som viser alle dataendringer som er gjort i radene i resultatsettet når denne markøren vises. Dataverdiene, rekkefølgen og radmedlemskapet i hvert utvalg kan variere. Valgalternativet ABSOLUTT støttes ikke av dynamiske markører.
. FAST_FORWARD– Indikerer en FORWARD_ONLY, READ_ONLY-markør som ytelsesoptimalisering er aktivert for. Alternativet FAST_FORWARD kan ikke spesifiseres med alternativene SCROLL eller FOR_UPDATE.
. SCROLL_LOCKS– Indikerer at posisjonerte oppdateringer eller slettinger gjort via markøren garantert vil lykkes. SQL Server låser rader når de leses inn i markøren for å sikre at de er tilgjengelige for påfølgende endringer. Alternativet SCROLL_LOCKS kan ikke spesifiseres med alternativet FAST_FORWARD eller STATIC.
. OPTIMISTISK– Indikerer at posisjonerte oppdateringer eller slettinger gjort via markøren vil mislykkes hvis raden har blitt oppdatert siden den ble lest inn i markøren. SQL Server låser ikke rader når de leses inn i markøren. I stedet blir det gjort en sammenligning av verdiene til tidsstempelkolonnen (eller kontrollsummer hvis tabellen ikke har en tidsstempelkolonne) for å finne ut om raden har endret seg siden den ble lest inn i markøren. Hvis en rad har blitt endret, er det ikke mulig å endre eller slette dens plassering. Alternativet OPTIMISTISK kan ikke spesifiseres med alternativet FAST_FORWARD.

5) Åpne markøren

6) Henter rader fra markøren

HENT [{NESTE|FØR|FØRSTE|SISTE|{ABSOLUTT|RELATIV }}]
FRA INN I

7) Alternativer for markørposisjonering
. NESTE|FØR|FØRSTE|SISTE– til neste|forrige|første|siste linje i resultatsettet.
. RELATIV ±N– til en linje med positiv eller negativ forskyvning i forhold til gjeldende linje.
. ABSOLUTT ±N– til en linje med et eksplisitt spesifisert absolutt posisjonsnummer fra begynnelsen eller slutten av markøren.

Merk: SQL Server tillater heltallsvariabelen @N i stedet for N.

8) Lukke markøren

9) Merknader om markører
. Hvis markøren inneholder mer enn én linje, er det nødvendig å organisere en løkke for å hente data fra den, med jevne mellomrom sjekke for å nå den siste linjen.
. I motsetning til tabeller og visninger, er markørrader ordnet enten eksplisitt ved hjelp av en seksjon REKKEFØLGE ETTER, eller i samsvar med konvensjonene vedtatt i et bestemt DBMS.
. Markørene brukes også til å velge grupper av rader fra tabeller, som kan oppdateres eller slettes en om gangen.
. For at en markør skal kunne oppdateres, må den oppfylle de samme kriteriene som visningen, det vil si ikke inneholde seksjoner UNION, ORDER BY, GROUP BY, DISTINCT.

10) Eksempel for sletting av data fra en markør

exec sql erklærer markør Cur1 for velg * fra kunde
hvor Vurdering
// print (@f1+’ ‘+convert(Varchar(5),@f2))
exec sql sletting fra kunden
hvor strøm av Cur1; ) – Ta data for å slette fra markøren
ikke ferdig:
exec sql lukk markør Cur1; — Lukk markøren
exit();

11) Eksempel på økende provisjoner

exec sql erklærer markør CurCust for velg * fra SalesPeople
hvor SNum inn (velg SNum fra Kunde der Rating=300); — Definer markøren
exec sql åpen markør CurCust; - Kjør markøren
while (sqlca.sqlcode==0) ( — Lag en sløyfe for å oppdatere data i tabellen
exec sql henter CurCust til:Id_num, :SalesPerson, :Loc, :Comm;
exec sql update SalesPeople sett Comm=Comm+.01 der gjeldende
av CurCust; ) – Ta dataene for oppdatering fra markøren
exec sql lukk markør CurCust; — Lukk markøren

SELECT S.Name, MAX(S.City) AS City, SUM(O.Amt) AS Amt FROM SalesPeople S INNER JOIN Ordrer O PÅ S.SNum=O.SNum GRUPPER ETTER S.Navn BESTILL ETTER 2

ERKLÆR Cur1 SCROLL CURSOR FOR SELECT S.Name, MAX(S.City) AS City, SUM(O.Amt) AS Amt FROM SalesPeople S INNER JOIN Bestillinger O PÅ S.SNum=O.SNum GRUPPER ETTER S.Navn BESTILL ETTER 2
ÅPEN Cur1
HENT NESTE FRA Cur1
WHILE @@FETCH_STATUS=0
BEGYNNE
HENT NESTE FRA Cur1
SLUTT
LUKK Cur1
TILDELE Cur1