Tar bort från ms sql-markören. Markörer i MySQL lagrade procedurer. A. Använda en enkel markör och syntax

Definitionen av markören är given. En beskrivning av dess typer och beteende ges: statiska, dynamiska, sekventiella och nyckelmarkörer. Principerna för markörkontroll beskrivs: skapa och öppna en markör, läsa data, stänga en markör. Exempel på markörprogrammering ges.

Markör koncept

En fråga mot en relationsdatabas returnerar vanligtvis flera rader (poster) med data, men applikationen bearbetar bara en post åt gången. Även om det handlar om flera rader samtidigt (till exempel visa data i form av kalkylblad), är deras antal fortfarande begränsat. Dessutom, när du ändrar, tar bort eller lägger till data, är arbetsenheten serien. I denna situation kommer begreppet markör i förgrunden, och i detta sammanhang är markören en pekare till en rad.

En markör i SQL är ett område i databasminnet som är utformat för att hålla den sista SQL-satsen. Om den aktuella satsen är en databasfråga, lagras också en rad med frågedata som kallas det aktuella värdet, eller den aktuella markörraden, i minnet. Det angivna området i minnet namnges och är tillgängligt för applikationsprogram.

Vanligtvis används markörer för att välja från en databas en delmängd av informationen som lagras i den. Vid varje given tidpunkt kan en markörrad kontrolleras av applikationsprogrammet. Markörer används ofta i SQL-satser inbäddade i applikationsprogram skrivna på procedurspråk. Vissa av dem skapas implicit av databasservern, medan andra definieras av programmerare.

I enlighet med SQL-standarden, när du arbetar med markörer, kan följande huvudåtgärder urskiljas:

  • skapande eller markördeklaration;
  • öppningsmarkören, dvs. fylla den med data som är lagrad i flernivåminne;
  • val från markören och ändra datarader med den;
  • stänger markören, varefter den blir otillgänglig för användarprogram;
  • frigör markören, dvs. ta bort markören som ett objekt eftersom att stänga den inte nödvändigtvis frigör minnet som är associerat med det.

Definitionen av en markör kan variera något mellan olika implementeringar. Till exempel, ibland måste en utvecklare explicit frigöra minnet som tilldelats för en markör. Efter släpp markören dess tillhörande minne frigörs också. Detta gör det möjligt att återanvända hans namn. I andra implementeringar när stänger markören frigöring av minne sker implicit. Omedelbart efter återställning blir den tillgänglig för andra operationer: öppnar en annan markör etc.

I vissa fall är det oundvikligt att använda en markör. Om möjligt bör detta dock undvikas och arbeta med vanliga databearbetningskommandon: SELECT, UPDATE, INSERT, DELETE. Förutom det faktum att markörer inte tillåter modifieringsoperationer på hela datavolymen, är hastigheten för att utföra databehandlingsoperationer med hjälp av en markör märkbart lägre än den för standardmedel SQL.

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

SQL Server stöder tre typer av markörer:

  • SQL-markörer används främst inom triggers, lagrade procedurer och skript;
  • servermarkörer arbetar på servern och implementerar applikationsprogrammeringsgränssnittet för ODBC, OLE DB, DB_Library;
  • Klientmarkörer implementeras på själva klienten. De hämtar hela resultatuppsättningen med rader från servern och lagrar den lokalt, vilket påskyndar databehandlingen genom att minska tidsspillan som spenderas på nätverksdrift.

Olika typer av fleranvändarapplikationer kräver olika typer av parallell åtkomst till data. Vissa applikationer kräver omedelbar tillgång till information om ändringar i databasen. Detta är typiskt för biljettbokningssystem. I andra fall, såsom statistiska rapporteringssystem, är datastabilitet viktig eftersom om den ständigt modifieras kommer program inte att kunna visa information effektivt. Olika applikationer behöver olika implementeringar av markörer.

I SQL Server varierar markörtyperna i de funktioner de tillhandahåller. Markörtypen bestäms när den skapas och kan inte ändras. Vissa typer av markörer kan upptäcka ändringar som gjorts av andra användare på rader som ingår i resultatuppsättningen. SQL Server spårar dock bara ändringar av sådana rader medan raden används och tillåter inte ändringar att ändras när raden redan har lästs.

Markörerna är indelade i två kategorier: sekventiell och rullningsbar. I följd låter dig välja data i endast en riktning - från början till slut. Bläddringsbara markörer ge större handlingsfrihet - det är möjligt att röra sig i båda riktningarna och hoppa till en godtycklig rad av markörens resultatuppsättning Om programmet kan modifiera de data som markören pekar på kallas det rullbar och modifierbar. På tal om markörer, vi bör inte glömma transaktionsisolering. När en användare ändrar en post, läser en annan den med sin egen markör, och dessutom kan han modifiera samma post, vilket gör det nödvändigt att upprätthålla dataintegriteten.

SQL Server stöder statisk, dynamisk, sekventiell och styrs av en uppsättning nycklar.

I schemat med statisk markör information läses från databasen en gång och lagras som en ögonblicksbild (vid någon tidpunkt), så ändringar som gjorts i databasen av en annan användare är inte synliga. Ett tag öppnar markören servern sätter ett lås på alla rader som ingår i dess fullständiga resultatuppsättning. Statisk markörändras inte efter skapandet och visar alltid den datauppsättning som fanns när den öppnades.

Om andra användare ändrar data som ingår i markören i källtabellen kommer detta inte att påverka statisk markör.

I statisk markör Det går inte att göra ändringar, så det öppnas alltid i skrivskyddat läge.

Dynamisk markör upprätthåller data i ett "live" tillstånd, men detta kräver nätverks- och mjukvaruresurser. Använder sig av dynamiska markörer en fullständig kopia av källdata skapas inte, utan ett dynamiskt urval görs från källtabellerna endast när användaren kommer åt vissa data. Under hämtningen låser servern raderna och alla ändringar som användaren gör i markörens fullständiga resultatuppsättning kommer att synas i markören. Men om en annan användare har gjort ändringar efter att markören har hämtat data, kommer de inte att återspeglas i markören.

Markören styrs av en uppsättning tangenter, är i mitten mellan dessa ytterligheter. Poster identifieras vid tidpunkten för provtagning, och på så sätt spåras ändringar. Den här typen av markör är användbar när du implementerar rullning bakåt - då är tillägg och raderingar av rader inte synliga förrän informationen uppdateras och föraren väljer ny version register, om ändringar har gjorts i dem.

Sekventiella markörer får inte hämta data i motsatt riktning. Användaren kan bara välja rader från början till slutet av markören. Seriell markör lagrar inte en uppsättning av alla rader. De läses från databasen så fort de väljs i markören, vilket gör att alla ändringar som görs av användare i databasen kan reflekteras dynamiskt med kommandona INSERT, UPDATE, DELETE. Markören visar det senaste tillståndet för data.

Statiska markörer ge en stabil bild av data. De är bra för informations-"lager"-system: applikationer för rapporteringssystem eller för statistiska och analytiska ändamål. Förutom, statisk markör klarar bättre än andra med att sampla stora datamängder. Däremot kräver elektroniska inköps- eller biljettbokningssystem dynamisk uppfattning om uppdaterad information när ändringar görs. I sådana fall används det dynamisk markör. I dessa applikationer är mängden data som överförs vanligtvis liten och nås på radnivå (individuell post). Gruppåtkomst är mycket sällsynt.

Markörhantering i MS SQL Server-miljö

Markörkontroll implementeras genom att utföra följande kommandon:

  • DEKLARE - skapande eller markördeklaration;
  • ÖPPEN - öppningsmarkören, dvs. fylla den med data;
  • HÄMTA val från markören och ändra datarader med hjälp av markören;
  • STÄNGA - stänger markören;
  • AVDELA – frigör markören, dvs. radera markören som ett objekt.

Markördeklaration

SQL-standarden tillhandahåller följande kommando för att skapa en markör:

Användning av nyckelordet INSENSITIVE kommer att skapa statisk markör. Data ändrasär inte tillåtna och ändringar gjorda av andra användare visas inte. Om nyckelordet INSENSITIVE saknas, a dynamisk markör.

När du anger nyckelordet SCROLL kan den skapade markören rullas i valfri riktning, så att du kan använda valfri valkommandon. Om detta argument utelämnas kommer markören att vara konsekvent, dvs. dess visning kommer bara att vara möjlig i en riktning - från början till slut.

SELECT-satsen anger kroppen för SELECT-begäran, som bestämmer den resulterande uppsättningen rader för markören.

Att specificera FOR READ_ONLY skapar en skrivskyddad markör och tillåter inga ändringar av data. Den skiljer sig från statisk, även om den senare inte heller tillåter att data ändras. Kan deklareras som en skrivskyddad markör dynamisk markör, vilket gör att ändringar gjorda av en annan användare kan visas.

Genom att skapa en markör med ett FOR UPDATE-argument kan du köra i markören dataändring antingen i de angivna kolumnerna eller, i avsaknad av argumentet OF kolumnnamn, i alla kolumner.

I MS SQL Server-miljön accepteras följande syntax för kommandot för att skapa markör:

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

Genom att använda nyckelordet LOCAL skapas en lokal markör som endast är synlig inom ramen för paketet, triggern, lagrad procedur eller anpassad funktion. När ett paket, utlösare, procedur eller funktion avslutas, förstörs markören implicit. För att skicka innehållet i markören utanför konstruktionen som skapade den, måste du tilldela ett OUTPUT-argument till dess parameter.

Om nyckelordet GLOBAL anges skapas en global markör; den existerar tills den aktuella anslutningen stängs.

Om du anger FORWARD_ONLY skapas seriell markör; Data kan endast samplas i riktningen från den första raden till den sista.

Genom att specificera SCROLL skapas rullbar markör; Data kan nås i valfri ordning och i vilken riktning som helst.

Ange STATIC skapar statisk markör.

Genom att specificera KEYSET skapas en tangentmarkör.

Ange DYNAMIC skapar dynamisk markör.

Om du anger FAST_FORWARD-argumentet för en READ_ONLY-markör, kommer den skapade markören att optimeras för snabb åtkomst till datan. Detta argument kan inte användas tillsammans med argumenten FORWARD_ONLY eller OPTIMISTIC.

En markör som skapats med argumentet OPTIMISTIC förhindrar modifiering eller radering av rader som modifierades efter öppnar markören.

Genom att ange argumentet TYPE_WARNING kommer servern att informera användaren om en implicit ändring av markörtypen om den är inkompatibel med SELECT-frågan.

Öppnar markören

För öppnar markören och fyll den med data från SELECT-frågan som angavs när markören skapades, använd följande kommando:

Efter öppnar markören Den associerade SELECT-satsen exekveras, vars utdata lagras i flernivåminne.

Hämtar data från en markör

Direkt efter öppnar markören du kan välja dess innehåll (resultatet av att köra motsvarande fråga) med följande kommando:

Om du anger FIRST returneras den allra första raden av markörens kompletta resultatuppsättning, som blir den aktuella raden.

Om du anger LAST returneras den senaste raden på markören. Det blir också den nuvarande linjen.

Om du anger NEXT returneras raden omedelbart efter den nuvarande i hela resultatuppsättningen. Nu blir det aktuellt. Som standard använder FETCH-kommandot den här metoden för att hämta rader.

Nyckelordet PRIOR returnerar raden före det aktuella. Det blir aktuellt.

Argument ABSOLUT (line_number | @line_number_variable) returnerar en rad med dess absoluta ordningsnummer i markörens fullständiga resultatuppsättning. Radnumret kan anges med en konstant eller som namnet på en variabel i vilken radnumret är lagrat. Variabeln måste vara en heltalsdatatyp. Både positiva och negativa värden anges. När du anger ett positivt värde räknas strängen från början av uppsättningen, medan ett negativt värde räknas från slutet. Den valda raden blir den aktuella raden. Om ett nollvärde anges returneras ingen rad.

Argument RELATIV (antal rader | @variabelt antal rader) returnerar raden som är det angivna antalet rader efter den aktuella. Om du anger ett negativt antal rader kommer raden som är det angivna antalet rader före den nuvarande att returneras. Om du anger ett nollvärde returneras den aktuella raden. Den returnerade raden blir den aktuella raden.

Till öppna global markör, måste du ange nyckelordet GLOBAL före dess namn. Markörens namn kan också anges med en variabel.

I design INTO @variabelnamn [,...n] en lista med variabler specificeras där motsvarande kolumnvärden för den returnerade raden kommer att lagras. Ordningen för att specificera variabler måste matcha ordningen på kolumnerna i markören, och datatypen för variabeln måste matcha datatypen i markörkolumnen. Om INTO-konstruktionen inte är specificerad, kommer beteendet för FETCH-kommandot att likna beteendet för SELECT-kommandot - data visas på skärmen.

Ändra och radera data

För att göra ändringar med hjälp av en markör måste du utfärda ett UPDATE-kommando i följande format:

Flera kolumner i den aktuella markörraden kan ändras i en operation, men alla måste tillhöra samma tabell.

För att radera data med hjälp av en markör, använd kommandot DELETE i följande format:

Som ett resultat kommer linjeuppsättningsströmmen i markören att raderas.

Stänger markören

Efter stängning blir markören oåtkomlig för programanvändare. När den är stängd tas alla lås som installerats under driften bort. Stängning kan endast tillämpas på öppna markörer. Stängt men inte frigjord markör kan öppnas igen. Det är inte tillåtet att stänga en oöppnad markör.

Släpp markören

Stänger markören frigör inte nödvändigtvis minnet som är associerat med det. Vissa implementeringar måste uttryckligen avallokera det med hjälp av DEALLOCATE-satsen. Efter släpp markören Minnet frigörs också, vilket gör det möjligt att återanvända markörnamnet.

För att kontrollera om slutet av markören har nåtts, rekommenderas att använda funktionen: @@FETCH_STATUS

Funktionen @@FETCH_STATUS returnerar:

0 om hämtningen lyckades;

1 om hämtningen misslyckades på grund av ett försök att hämta en rad utanför markören;

2 om hämtningen misslyckades på grund av ett försök att komma åt en raderad eller ändrad 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 "Inköpslista" DECLARE klient_cursor CURSOR LOCAL FÖR VALD klientkod, företag, efternamn FRÅN klient WHERE City="Moscow" BESTÄLLNING EFTER Företag, Efternamn ÖPPNA klient_cursor HÄMTA NÄSTA FRÅN klient_cursor INTO @id_kl, @firm, @fam WHILE @@FETCH_STATUS =0 BÖRJA VÄLJ @message="Klient "+@fam+ "Företag "+ @firm PRINT @message SELECT @message="Produktnamn Inköpsdatum Kostnad" SKRIV UT @message DEKLARERA tovar_cursor CURSOR FOR SELECT Product.Name, Transaction.Date, Product .Pris* Transaktionskvantitet SOM kostnad FRÅN Produkt INNER JOIN Transaktion PÅ Produkt. Produktkod=Transaktion.Produktkod VAR Transaktion.Kundkod=@id_kl ÖPPNA tovar_cursor HÄMTA NÄSTA FRÅN tovar_cursor INTO @nam, @d, @p IF @@FETCH_STATUS<>0 SKRIV UT "Inga köp" MEDAN @@FETCH_STATUS=0 BÖRJA VÄLJ @message=" "+@nam+" "+ CAST(@d AS CHAR(12))+" "+ CAST(@p AS CHAR(6)) PRINT @message SET @s=@s+@p HÄMTA NÄSTA FRÅN tovar_cursor INTO @nam, @d, @p AVSLUTA STÄNG tovar_cursor DEALLOCATE tovar_cursor SELECT @message="Total kostnad "+ CAST(@s AS CHAR(6)) PRINT @message -- flytta till nästa klient-- HÄMTA NÄSTA FRÅN klient_cursor INTO @id_kl, @firm, @fam AVSLUTA STÄNG klient_cursor DEALLOCATE klient_cursor Exempel 13.6. Markör för att visa en lista över varor köpta av kunder från Moskva och deras totala kostnad.

Exempel 13.7. Utveckla en rullningsbar markör för kunder från Moskva. Om telefonnumret börjar med 1, radera klienten med det numret och i den första markörposten ersätt den första siffran i telefonnumret med 4.

DECLARE @firm VARCHAR(50), @fam VARCHAR(50), @tel VARCHAR(8), @message VARCHAR(80) PRINT "Lista of clients" DECLARE klient_cursor CURSOR GLOBAL SCROLL KEYSET FOR SELECT Firm, Efternamn, Phone FROM Client WHERE City ="Moscow" BESTÄLLNING EFTER Företag, Efternamn FÖR UPPDATERING ÖPPNA klient_cursor HÄMTA NÄSTA FRÅN klient_cursor INTO @firm, @fam, @tel MEDAN @@FETCH_STATUS=0 BÖRJA VÄLJ @message="Client "+@fam+ " Företag "+ @firm " Phone "+ @tel SKRIV UT @meddelande -- om telefonnumret börjar med 1, -- radera klienten med det numret OM @tel LIKE '1%' RADERA klient DÄR AKTUELL AV klient_cursor ANNAT -- gå till nästa klient HÄMTA NÄSTA FRÅN klient_cursor INTO @firm, @fam, @tel AVSLUTA HÄMTA ABSOLUTE 1 FRÅN klient_cursor INTO @firm, @fam, @tel -- i den första posten, ersätt den första siffran i telefonnumret med 4 UPPDATERA Client SET Phone ='4' + RIGHT(@ tel,LEN(@tel)-1)) WHERE CURRENT OF klient_cursor SELECT @message="Client "+@fam+" Firm "+ @firm "Phone "+ @tel PRINT @message STÄNG klient_cursor DEALLOCATE klient_cursor Exempel 13.7. Scrollbar markör för klienter från Moskva.

Exempel 13.8. Användande markören som en utdataparameter för proceduren. Proceduren returnerar en datamängd - en lista över produkter.

Att anropa proceduren och skriva ut data från utmatningsmarkören utförs enligt följande:

DECLARE @my_cur CURSOR DECLARE @n VARCHAR(20) EXEC my_proc @cur=@my_cur OUTPUT HÄMTA NÄSTA FRÅN @my_cur INTO @n VÄLJ @n MEDAN (@@FETCH_STATUS=0) BÖRJA HÄMTA NÄSTA FRÅN @my_cur INTO @n SELECT AVSLUTA STÄNG @my_cur DEALLOCATE @my_cur


Markören är en länk till det kontextuella minnesområdet. I vissa implementeringar av SQL-programmeringsspråket (Oracle, Microsoft SQL Server) - resultatuppsättningen som erhålls vid exekvering av en fråga och den tillhörande aktuella postpekaren. Jag skulle säga att markören är virtuellt bord som är ett alternativt datalager. I det här fallet låter markören dig komma åt dess data som om det vore data från en vanlig array.
Markörer används i lagrade procedurer. Nog med teori, låt oss titta på ett exempel:
Vi har en databas (databasen är lite dålig, det här är en av mina laboratoriearbete, men vår databaslärare insisterade på en sådan struktur)
/*Bank Information*/
SKAPA TABELL "bank" (

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


PRIMÄRNYCKEL ('BankId')

)ENGINE=InnoDB
TECKENSET "utf8" SAMLA "utf8_bin" ;
/*data om insättningar */
SKAPA TABELL "bankdistribution" (
`BankId` INTEGER (11) INTE NULL ,
`Persent` INTEGER (11) DEFAULT NULL ,
`ContributeAmount` DECIMAL (10,0) INTE NULL ,
`ClientId` INTEGER (11) INTE NULL ,
PRIMARY KEY(`BankId`, `ClientId`),
KEY `BankId` (`BankId`),
KEY `ClientId` (`ClientId`),
CONSTRAINT `bankdistribution_fk` FOREIGN KEY (`BankId`) REFERENCER `bank` (`BankId`),
BEGRÄNSNING `bankdistribution_fk1` FOREIGN KEY (`ClientId`) REFERENSER `client` (`ClientId`)
)ENGINE=InnoDB
/*data om investerare*/
SKAPA TABELL "klient" (
`ClientId` INTEGER (3) INTE NULL AUTO_INCREMENT,
`CreditCardId` BIGINT(10) NOT NULL ,
`Efternamn` VARCHAR (50) COLLATE utf8_bin INTE NULL DEFAULT "" ,
`Namn` VARCHAR (50) COLLATE utf8_bin INTE NULL DEFAULT "" ,
`FirstName` VARCHAR (50) COLLATE utf8_bin INTE NULL DEFAULT "" ,
`Telefon` VARCHAR (50) COLLATE utf8_bin INTE NULL DEFAULT "" ,
`Adress` VARCHAR (50) COLLATE utf8_bin NOT NULL DEFAULT "" ,
`SafeId` INTEGER (5) INTE NULL ,
PRIMARY KEY(`ClientId`, `CreditCardId`),
KEY `ClientId` (`ClientId`)

)ENGINE=InnoDB
AUTO_INCREMENT=11 TECKENSET "utf8" SAMLA "utf8_bin"

Låt oss säga att vi behöver ta emot varje bank i tur och ordning och utföra några åtgärder med den, följande fråga kan hjälpa oss med detta

Välj `bank`.* FRÅN `bank` LIMIT NUMBER OF THE_RECORD_WE NEED,1
. Med hjälp av LIMIT WE NEED_RECORD NUMBER, 1 extraherar vi alltså varje post i en loop från banktabellen och utför de åtgärder vi behöver med den, samtidigt som vi ökar värdet på WE NEED_RECORD NUMBER med 1. Nu kommer vi att göra samma sak men med en markören
Börja
/* variabler där vi extraherar data */
Deklarera vBankId heltal ;
Deklarera vBankName VARCHAR(50);
Deklarera vAddress VARCHAR(50);
Deklarera vPhone VARCHAR (50);
/* hadler variabel - a*/
Deklarera gjort heltal standard 0;
/*Markördeklaration*/
Deklarera BankCursor Cursor för Välj `bank`.`BankId`,`bank`.`BankName`,`bank`.`Address`,`bank`.`Phone`, FROM `bank` där 1;
/*HANDLER syfte, vilket kommer att förklaras nedan*/
DEKLARERA FORTSÄTT HANDLER FÖR SQLSTATE "02000" SET done=1;
/* öppna markören */
Öppna BankCursor;
/*hämta data*/
MEDAN gjort = 0 DO

vi vidtar de åtgärder vi behöver
AVSLUTA MED ;
/*stänger markören*/
Stäng BankCursor;
SLUTET ;

* Den här källkoden har markerats med Source Code Highlighter.

Fel: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)

Meddelande: Inga data - noll rader hämtade, markerade eller bearbetade

SQLSTATE: 02000 aktiveras när slutet av markören nås, eller när select eller update returnerar en tom sträng.

Nästa rad deklarerade vi markören DECLARE cursor_name CURSOR FOR select_statement;
Öppna markören Öppna cursor_name;
Sedan, tills vi når slutet av markören (MEDAN gjort = 0 DO), extraherar vi data och bearbetar den.
Du måste stänga markören innan du avslutar den lagrade proceduren. Stäng cursor_name;

Det verkar inte komplicerat. Men det finns många fallgropar förknippade med SQLSTATE "02000".

MEDAN gjort = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;

Välj (ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution där BankId = vBankId limit 1;
vi gör några åtgärder
AVSLUTA MED ;

* Den här källkoden har markerats med Source Code Highlighter.


Allt är bra och korrekt ur syntaxsynpunkt. Men ur en logisk synvinkel, nej. Det kan hända att insättare inte har öppnat konton i någon bank, då för Välj (ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution där BankId = vBankId limit 1; SQLSTATE: 02000 aktiveras, variabeln done sätts till 1, och medan loop slutar tidigare än vi förväntat oss. Detta kan undvikas genom att göra följande
MEDAN gjort = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* extrahera för banken beloppet för någon av dess insättningar */


if (vContributeAmountSUM > 0) då
/* extrahera för banken beloppet för någon av dess insättningar */

sluta om ;
vi gör några åtgärder
AVSLUTA MED ;

* Den här källkoden har markerats med Source Code Highlighter.


Med den första begäran kontrollerade vi om det finns bidrag (om det inte finns några, då vContributeAmountSUM == 0) och endast om det finns några, hämtar vi data.

Låt oss nu säga att vi måste ta bort det totala beloppet på konton i olika banker för varje kund
Deklarera ClientSummCursor Cursor för Välj summa

Deklarera ClientSummCursor Cursor för Välj summa (`bankdistribution`.`ContributeAmount`), `bankdistribution`.`ClientId` FRÅN `bankdistribution` Inner Join client på (client.ClientId = bankdistribution.`ClientId`) där 1 grupp efter `bankdistribution`. `ClientId`;

Öppna ClientSummCursor;
MEDAN gjort = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* extrahera för banken beloppet för någon av dess insättningar */
Välj Count(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution där BankId = vBankId limit 1;
/* kontrollera om det verkligen finns insättningar på denna bank */
if (vContributeAmountSUM > 0) då
/* extrahera för banken beloppet för någon av dess insättningar */
Välj ContributeAmount INTO vContributeAmountSUM FROM bankdistribution där BankId = vBankId limit 1;
sluta om ;


vi gör några åtgärder.
AVSLUTA MED ;

* Den här källkoden har markerats med Source Code Highlighter.

Samma situation kan uppstå när data i ClientSummCursor-markören slutar tidigare än data i BankCursor, SQLSTATE: 02000 triggas, done-variabeln sätts till 1 och while-loopen slutar tidigare än vi förväntat oss. Detta kan undvikas genom att göra följande

Öppna ClientSummCursor;
MEDAN gjort = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* extrahera för banken beloppet för någon av dess insättningar */
Välj Count(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution där BankId = vBankId limit 1;
/* kontrollera om det verkligen finns insättningar på denna bank */
if (vContributeAmountSUM > 0) då
/* extrahera för banken beloppet för någon av dess insättningar */
Välj ContributeAmount INTO vContributeAmountSUM FROM bankdistribution där BankId = vBankId limit 1;
sluta om ;
/* innan du extraherar data från den andra markören, kom ihåg sqlstate-tillståndet */
SET old_status = klar;
/* extrahera data vi behöver */
FETCH ClientSummCursor INTO vSum,vClientId;
/* kontrollera om data hämtades och om sqlstate 0200 misslyckades */
om (klar = 0) då
vi gör några åtgärder.
sluta om ;
/* före slutet av stunden, återställ värdet för den klara variabeln */
set done = old_status;
AVSLUTA MED ;

* Den här källkoden har markerats med Source Code Highlighter.

Tack till alla som har läst så här långt, jag hoppas att detta kommer att vara användbart för någon.

DET GÄLLER: SQL Server (sedan 2008) Base SQL-data Azure SQL Data WarehouseParallel Data Warehouse

Definierar attribut för en Transact-SQL-servermarkör, såsom vyegenskaper och frågan som används för att bygga resultatuppsättningen som markören arbetar på. DECLARE CURSOR-satsen stöder både ISO-standardsyntax och syntax som använder Transact-SQL-språktilläggsuppsättningen.

ISO syntax DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR FOR select_statement [FÖR (LÄS ENDAST | UPPDATERA [AV kolumnnamn [,...n]])] [;] Transact-SQL Extended Syntax DECLARE cursor_name CURSOR [ LOKAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATISK | NYCKELSET | DYNAMISK | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ] FÖR select_statement [ FÖR UPPDATERING [ AV kolumnnamn [ ,...n ] ] ] [;]

cursor_name
cursor_name

OKÄNSLIG
tempdb; sålunda återspeglas inte ändringar i de underliggande tabellerna i data som returneras av denna markörs val, och den här markören kan inte ändras. När du använder ISO-syntax, såvida inte alternativet INSENSITIVE är specificerat, visas bekräftade uppdateringar och raderingar gjorda av bastabellerna i efterföljande val.

SKROLLA
Indikerar att alla samplingsalternativ är tillgängliga (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE). Om ISO DECLARE CURSOR-satsen inte anger ett SCROLL-alternativ, stöds endast alternativet NEXT fetch. Alternativet SCROLL kan inte specificeras med alternativet FAST_FORWARD.

select_statement
Standard SELECT-sats, som definierar resultatuppsättningen för markören. Nyckelord FOR Browse och INTO är inte tillåtna select_statement markördeklaration.

select_statement konflikt med en markör av den begärda typen.

LÄS ENDAST

Uppdatering ]
kolumnnamn [, .. .n] anges, tillåter endast de listade kolumnerna ändringar. Om UPDATE-satsen används utan en lista med kolumner, är uppdateringen möjlig för alla kolumner.

cursor_name
Transact-SQL-namnet för den specifika servermarkören. cursor_name måste följa reglerna för identifierare.

LOKAL
Indikerar att markören är lokal för paketet, den lagrade proceduren eller triggern där den skapades. Markörnamnet är endast giltigt inom detta område. En markör kan refereras av lokala paketvariabler, lagrade procedurer, triggers eller utdataparametern för en lagrad procedur. OUTPUT-parametern används för att skicka en lokal markör till det anropande paketet, den lagrade proceduren eller triggern, som sedan kan tilldela parametern till en markörvariabel för efterföljande åtkomst till markören efter att den lagrade proceduren är klar. Markören släpps implicit när batchen, den lagrade proceduren eller triggern slutför exekveringen, såvida inte markören skickades till parametern OUTPUT. Om markören skickades till parametern OUTPUT, släpps markören när alla variabler som refererar till den frigörs eller när scopet lämnas.

GLOBAL
Indikerar att markören är global för anslutningen. Markörnamnet kan användas av alla lagrade förfaranden eller paket som körs på anslutningen. Markören släpps implicit endast om anslutningen bryts.

FORWARD_ONLY
Anger att markören endast kan ses från första till sista raden. Endast hämtningsalternativet FETCH NEXT stöds. Om FORWARD_ONLY anges utan nyckelorden STATIC, KEYSET eller DYNAMIC, beter sig markören som en DYNAMISK markör. Om varken FORWARD_ONLY-argumentet eller SCROLL-argumentet anges, är standardargumentet FORWARD_ONLY om inte nyckelorden STATIC, KEYSET eller DYNAMIC finns. STATIC, KEYSET och DYNAMIC markörer har ett standardvärde på SCROLL. Till skillnad från databas-API:er som ODBC och ADO, stöds FORWARD_ONLY-läget av följande Transact-SQL-markörer: STATIC, KEYSET och DYNAMIC.

STATISK
Definierar en markör som skapar en tillfällig kopia av data för användning av markören. Alla frågor till markören kommer åt den angivna temporära tabellen i tempdb; sålunda återspeglas inte ändringar i de underliggande tabellerna i data som returneras av denna markörs val, och den här markören kan inte ändras.

KEYSET
Indikerar att medlemskapet eller ordningen för raderna i markören är oförändrad när den öppnas. En uppsättning nycklar som unikt identifierar rader är inbyggd i tabellen tempdb kallad nycklar.

Ändringar av icke-nyckelvärden i bastabeller gjorda av markörägaren eller utförda av andra användare visas när markörägaren visar den. Ändringar gjorda av andra användare återspeglas inte (ändringar kan inte göras med hjälp av Transact-SQL-servermarkören). Om en rad raderas, returnerar ett försök att hämta rader @@FETCH_STATUS -2. Uppdateringar av nyckelvärden på grund av markörgränser liknar att ta bort en gammal rad och sedan infoga den ny linje. Raden med de nya värdena är inte synlig och försöker hämta raden med de gamla värdena returnerar @@FETCH_STATUS -2. Uppdateringar är synliga omedelbart om de görs genom markören med hjälp av WHERE CURRENT OF-satsen.

DYNAMISK
Definierar en markör som visar alla dataändringar som gjorts på rader i resultatuppsättningen medan du tittar på den här markören. Datavärden, ordning och radmedlemskap i varje val kan variera. Alternativet ABSOLUT stöds inte av dynamiska markörer.

SNABBSPOLA
Indikerar en FORWARD_ONLY, READ_ONLY markör som har prestandaoptimering aktiverad. Alternativet FAST_FORWARD kan inte anges med alternativen SCROLL eller FOR_UPDATE.

READ_ONLY
Förhindrar ändringar som görs med den här markören. WHERE CURRENT OF-satsen kan inte referera till en markör i en UPDATE- eller DELETE-sats. Det här alternativet har företräde framför standardfunktionen för marköruppdatering.

SCROLL_LOCKS
Indikerar att positionerade uppdateringar eller raderingar som görs med markören garanterat kommer att lyckas. SQL Server låser rader när de läses in i markören för att säkerställa att dessa rader är tillgängliga för efterföljande ändringar. Alternativet SCROLL_LOCKS kan inte specificeras med alternativet FAST_FORWARD eller STATIC.

OPTIMISTISK
Anger att positionerade uppdateringar eller borttagningar som görs med markören kommer att misslyckas om raden har uppdaterats sedan den lästes in i markören. SQL Server låser inte rader när de läses in i markören. Jämförelser används istället tidsstämpel kolumnvärden eller kontrollsummor om tabellen inte har tidsstämpel kolumn för att avgöra om raden har ändrats sedan den lästes in i markören. Om raden har ändrats kommer försök till en positionerad uppdatering eller radering att misslyckas. Alternativet OPTIMISTISK kan inte specificeras med alternativet FAST_FORWARD.

TYPE_WARNING
Anger att en varning kommer att skickas till klienten om markören implicit konverteras från en begärd typ till en annan.

select_statement
En standard SELECT-sats som anger resultatuppsättningen för en markör. Nyckelorden COMPUTE, COMPUTE BY, FOR Browse och INTO är inte tillåtna i select_statement markördeklaration.

SQL Server konverterar implicit markören till en annan typ om satserna in select_statement konflikt med en markör av den begärda typen. För mer information, se Implicita marköromvandlingar.

FÖR UPPDATERING ]
Definierar kolumnerna i markören som ska uppdateras. Om OF kolumnnamn [, ... n] tillhandahålls, endast de listade kolumnerna tillåter ändringar. Om UPDATE-satsen används utan en kolumnlista är uppdateringen möjlig för alla kolumner om inte samtidighetsalternativet READ_ONLY har angetts.

DECLARE CURSOR-satsen definierar attribut för en Transact-SQL-servermarkör, såsom vyegenskaper och frågan som används för att bygga resultatuppsättningen som markören arbetar på. OPEN-satsen fyller i resultatuppsättningen och FETCH-satsen returnerar en rad från den. CLOSE-satsen rensar den aktuella resultatuppsättningen som är kopplad till markören. DEALLOCATE-satsen frigör resurser som används av markören.

Den första formen av DECLARE CURSOR-satsen använder ISO-syntax för att specificera markörparametrar. Den andra formen av DECLARE CURSOR-satsen använder tillägg till Transact-SQL-språket som låter dig definiera markörer med samma typer som de som används i markörfunktionerna i databas-API:er som ODBC och ADO.

Dessa två former kan inte blandas. Om du anger SCROLL eller utelämnar nyckelord före nyckelordet CURSOR, kan du inte använda nyckelord mellan CURSOR och även för select_statement nyckelord. När du anger nyckelord mellan CURSOR, såväl som för select_statement nyckelord kan du inte ange SCROLL eller INSENSITIVE före nyckelordet CURSOR.

Om du använder Transact-SQL-syntax för DECLARE CURSOR-satsen och inte anger alternativen READ_ONLY, OPTIMISTIC eller SCROLL_LOCKS, antas följande standardvärde.

    Om SELECT-satsen inte stöder uppdateringar (eller har otillräckliga behörigheter, eller har åtkomst till fjärrtabeller som inte stöder uppdateringar, etc.), är markören inställd på READ_ONLY.

    STATIC och FAST_FORWARD markörer är som standard READ_ONLY.

    DYNAMIC och KEYSET-markörer är som standard OPTIMISTISK.

Markörer kan endast refereras av andra Transact-SQL-satser. Databas API-funktioner kan inte referera till markörer. Till exempel, när en markör har deklarerats kan OLE DB-, ODBC- eller ADO-funktioner och -metoder inte referera till dess namn. Markörrader kan inte väljas med motsvarande API-funktioner och metoder; För detta ändamål måste du använda Transact-SQL FETCH-satser.

Följande lagrade procedurer kan användas för att definiera egenskaperna för en markör efter att den har deklarerats.

Variabler kan användas som en del select_statement, där markören deklareras. Värdena på markörvariabler ändras inte efter att de har deklarerats.

Som standard ges DECLARE CURSOR-behörigheter till alla användare som har SELECT-behörighet för de vyer, tabeller och kolumner som används av markören.

Du kan inte använda markörer eller utlösare i en tabell med ett klustrat kolumnlagerindex. Denna begränsning gäller inte för icke-klustrade index; Du kan använda markörer och utlösare i en tabell med ett icke-klusterat kolumnlagerindex.

A. Använda en enkel markör och syntax

Resultatuppsättningen som skapas när du öppnar den här markören inkluderar alla rader och kolumner i tabellen. Denna markör kan uppdateras, alla uppdateringar och raderingar representeras i valet för denna markör. FETCH``NEXT hämtas endast eftersom parametern SCROLL inte specificerades.

DECLARE vend_cursor CURSOR FOR SELECT * FROM Purchasing.Vendor OPEN vend_cursor HÄMTA NÄSTA FRÅN vend_cursor;

B. Använda kapslade markörer för att visa en rapport

Följande exempel använder kapslade markörer för att visa en komplex rapport. En intern markör deklareras för varje leverantör.

STÄLL IN NOCOUNT PÅ ; DECLARE @vendor_id int , @vendor_name nvarchar ( 50 ), @message varchar ( 80 ), @product nvarchar ( 50 ); SKRIVA UT" -------- Rapport om leverantörsprodukter --------"; DECLARE vendor_cursor CURSOR FÖR VÄLJ leverantörs-ID, namn FRÅN Inköp.Vendor WHERE PreferredVendorStatus = 1 BESTÄLLNING EFTER leverantörs-ID;ÖPPNA vendor_cursor HÄMTA NÄSTA FRÅN vendor_cursor INTO @vendor_id, @vendor_name WHILE @@FETCH_STATUS = 0 BÖRJA UTSKRIFT " " VÄLJ @meddelande = "----- Produkter från leverantören: "+ @leverantörsnamn PRINT @meddelande -- Deklarera en inre markör baserad -- på vendor_id från den yttre 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 -- Variabelt värde från den yttre markören OPEN product_cursor HÄMTA NÄSTA FRÅN product_cursor INTO @product IF @@FETCH_STATUS<>0 SKRIV UT "<>" WHILE @@FETCH_STATUS = 0 BÖRJA VÄLJ @message = " " + @product PRINT @message HÄMTA NÄSTA FRÅN product_cursor INTO @product END CLOSE product_cursor DEALLOCATE product_cursor -- Hämta nästa leverantör. HÄMTA NÄSTA FRÅN vendor_cursor INTO @vendor_name, @vendor_name END CLOSE vendor_cursor; DEALLOCATE vendor_cursor;

Det kan mycket väl hända att svaret på en enkel klientförfrågan blir ett urval av hundratusentals rader, vilket är svårsmält för de flesta klienter. I det här fallet är lösningen på problemet med interaktion med klienter att använda markörer som en universell mekanism för att utbyta data mellan servern och klienten. Markörer arbetar med resultatuppsättningen data (resultatet av en fråga), vilket ger användarna ytterligare databehandlingsmöjligheter:

Markörer låter dig arbeta med tabellrader genom att ange deras serienummer i datamängden;

Markörer låter dig implementera komplexa datamodifieringsoperationer, till exempel när du ändrar värdet på en kolumn kräver att du upprepade gånger kommer åt värdena i andra kolumner.

Markörens livscykel:

Skapa en markör: DEKLARERA<имя курсора>[ INSENSITIVE ] [ SCROLL ] MARKÖR FÖR< SELECT -оператор>FÖR (LÄS ENDAST | UPPDATERA)

Här betyder nyckelordet INSENSITIVE att markören kommer att vara statisk (en ögonblicksbild av data), medan markören som standard skapas dynamiskt (hämtning utförs varje gång raden öppnas). Nyckelordet SCROLL betyder att markören kan rullas i vilken riktning som helst, annars skapas markören som en "sekventiell" markör.

Öppningsmarkör:ÖPPEN [GLOBAL]<имя курсора>. En markör som anges som GLOBAL raderas inte automatiskt när proceduren eller paketet som den anropades från slutar.

Läsningdata : HÄMTA [[ NÄSTA | FÖREGÅENDE | FÖRSTA | SISTA | ABSOLUT n | RELATIVE n ] FRÅN ] [ GLOBAL ]<имя курсора>[INTO@variabel_namn,...]. SQL Server 2000 låter dig läsa bara en rad från en markör. Det FÖRSTA nyckelordet är att returnera markörens första rad; LAST – sista raden på markören; NÄSTA – nästa rad efter den nuvarande, den returnerade raden blir den nuvarande; PRIOR – föregående före nuvarande; ABSOLUTE n – returnerar en rad med dess absoluta sekvensnummer i markören; RELATIVE – n rader efter den aktuella. Kolumndata kommer att lagras i var och en av de specificerade variablerna i den ordning de listas.

Ändra data: kör ett UPDATE-kommando med syntax designad för att arbeta med markörer.

Ta bort data: exekverar ett DELETE-kommando med syntax utformad för att fungera med markörer.

Stänger markören: STÄNG [GLOBAL]<имя курсора>

Släpp markören: AVALLOKERA [GLOBALT]<имя курсора>

Ett exempel på hur du använder en markör:

DECLARE fo_curs CURSOR STATIC FOR

VÄLJ namn_rus från för BESTÄLLNING AV namn_rus

DECLARE @name varchar(50)

HÄMTA FÖRST FRÅN fo_curs INTO @namn

WHILE @@FETCH_STATUS=0

HÄMTA NÄSTA FRÅN fo_curs INTO @namn

DEALLOCATE fo_curs

2.7. Säkerställande av datasäkerhet och integritet i Microsoft SQL Server. Databashantering. Roller. Tilldela rättigheter till användare (GIVNA, NEKA, ÅTERVÄNDA). Metoder och teknologier för dataskydd i SQL Server.

SQL Server säkerhet och administration. .

Huvuduppgiften för ett DBMS är att säkerställa integriteten och konsistensen av data inom det valda ämnesområdet. En av faktorerna som hindrar systemet från att lösa detta problem är handlingar från användare som av misstag eller avsiktligt försöker förstöra datastrukturen eller ändra själva data. Följaktligen måste DBMS skyddas inte bara från fysiska fel utan också från användare som är otillräckliga för de uppgifter som implementeras. För att göra detta är det nödvändigt att designa och ansluta ett säkerhetssystem till databasen som förhindrar användare från att utföra åtgärder utanför deras behörighet.

Databashantering

För att skapa en databas med TSQL, använd kommandot CREATE DATABASE, men vanligtvis används funktionerna i SQL Server Management Studio för detta ändamål. I SQL-server en hel del databasoperationer definieras: öka (minska) filstorlekar, ändra konfiguration (ALTER-kommando), bifoga och ta bort, överföra ägande, byta namn, visa egenskaper och slutligen ta bort (DROP DATABASE).

Som de flesta databasservrar har SQL Server en användare med fullständiga administrativa rättigheter - det här är Systemadministratör eller "sa". Efter den första serverinstallationen är sa-lösenordet tomt. Användaren som skapar en ny databas blir automatiskt dess ägare ('dbo' - Databasägare) Vid den tidpunkt då databasen skapas definieras även användaren "gäst". Om användarkontot inte är explicit mappat till en användare av en specifik databas, får användaren implicit åtkomst med att använda gästnamnet gäst.Gäst är vanligtvis förbjudet.

Användaren som skapar ett objekt i databasen blir automatiskt dess ägare, och ingen, inklusive dbo och sa, kan använda det objektet förrän ägaren tilldelar dem rättigheter till det. Men för att en användare ska kunna skapa ett objekt måste databasägaren först ge honom lämpliga rättigheter.

Roll låter dig kombinera användare som utför samma funktioner för att förenkla administrationen. Roller kan vara inbyggda eller anpassade. Inbyggda roller implementeras på servernivå och på databasnivå. Nedan finns en tabell över inbyggda databasroller:

db_ägare. Har alla rättigheter i databasen

Db_accessadmin. Kan lägga till eller ta bort användare

Db_securityadmin. Hanterar alla behörigheter, objekt, roller och användare

Db_ddladmin. Kan köra alla DDL-kommandon utom GRANT, DENY, REVOKE

Db_backupoperator. Archiver kan utföra kommandon. data

db_datareader. Kanske tittar. alla data i någon tabell

db_datawriter. Kanske en modifiering. alla data i någon tabell

Db_denydatareader. Förbjuden se kärlek data i någon tabeller

Db_denydatawriter. Förbjud modifiering av data i några tabeller

Tilldela rättigheter till användare. Grunden för SQL Server-säkerhet är (1) konton(räkenskaper); (2) användare; (3) roller; (4) grupper.

När en användare ansluter till SQL Server bestäms de åtgärder han kan utföra av de rättigheter som tilldelats honom som användare och medlem av en roll. Rättigheter beviljas av DBMS-administratören, databasägaren eller ägaren till ett specifikt databasobjekt. Rättigheter i databasen kan delas in i tre kategorier: (1) rättigheter att få åtkomst till databasobjekt; (2) rättigheter att utföra TSQL-kommandon; (3) implicita rättigheter. Servern låter dig överföra äganderätten från en användare till en annan.

Följande kommandon används för att hantera användarbehörigheter för att komma åt databasobjekt:

BEVILJA(ALLA |< вид действия >,…}

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

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

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

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

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

tilldela rättigheter till användare, Var

ALLA – användaren ges alla möjliga behörigheter, specificera annars

<вид действия>– rättigheter till åtgärder som är tillgängliga för användaren, nämligen:

VÄLJ – för vy, för tabellkolumn och för tabell (vy)

INSERT – för att lägga till, för tabellen (vyn) som helhet

UPPDATERING – för förändring, för en tabellkolumn och för en tabell (vy)

DELETE – för att ta bort, för tabellen (vyn) som helhet

EXECUTE – för att utföra lagrade procedurer

REFERENSER – möjligheten att referera till ett specificerat objekt (inkludera det som en del av en främmande nyckel).

<имя объекта системы безопасности>– SQL Server-konton, Windows-domänanvändare; PUBLIC – för alla användare.

MED BILJANDEALTERNATIV - tillåter användaren som för närvarande beviljas rättigheter att tilldela åtkomsträttigheter till objektet till andra användare.

SOM<имя группы> | <имя роли>– deltagande av en användare i en roll som ges möjlighet att ge rättigheter till andra användare.

GE VAL PÅ författare TILL allmänheten

BILJA INFOGA, UPPDATERA, DELETE PÅ författare TILL Mary, John, Tom

BIDRAG VAL PÅ Plan_Data TILL redovisning MED BIDRAG

BETYD VAL PÅ Plan_Data TILL Jack AS Accounting

Jack är inte medlem i redovisningsrollen, men någon i den rollen kan ge tillstånd

FÖRNEKA(ALLA |< вид действия >,…}

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

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

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

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

nekad åtkomst användare till databasobjekt. CASCADE återkallar rättigheter inte bara från given användare, men också för alla som han beviljat rättigheter.

Exempel (på kommandoförbud TSQL):

NEJ SKAPA BORD TILL Jack CASCADE

Team ÅTERKALLA används för att implicit neka åtkomst till databasobjekt. Syntaxen är densamma som kommandot DENY. Implicit nekande liknar att neka åtkomst, förutom att det bara gäller på den nivå som det är definierat på. Exempel: Användaren Jack, som är medlem i rollen GoodUsers, ges åtkomsträttigheter till XFiles-tabellen. Om REVOKE nekas för rollen GoodUsers att få åtkomst till denna tabell, kan Jack fortfarande komma åt den här tabellen eftersom rättigheterna för honom är explicit definierade. Om du använder REVOKE personligen åt honom kommer han att förlora rätten att få åtkomst till XFiles.

Behörigheter som ges till roller ärvs av deras medlemmar. Om en användare beviljas åtkomst till ett objekt genom medlemskap i en roll men nekad i en annan, så löses alltid åtkomstkonflikten till förmån för nekande.

Dataskyddsteknik i MS SQL Server

1. Mekanism kontrollpunkter– kontrollpunkter som genereras efter ~60 s för att skriva uppdaterade sidor till disken (en kontrollpunkt kan tvingas fram av kommandot CHECKPOINT).

2. Inbyggda och externa mekanismer för att kontrollera databasens integritet (startas automatiskt eller, som DBCC-verktyget - Database Consistency Checker - manuellt).

3. Fysisk duplicering (om tillåtet) av databasfiler med operativsystemet (inklusive mekanismen för speglade hårddiskar).

4. Säkerhetskopiera databaser och transaktionsloggar - genom att skriva en databasdump till en backupenhet (magnetband eller hårddisk).

5. Replikering – möjligheten att duplicera information genom att regelbundet (i vissa fall synkront) överföra den från en SQL-server till en annan.

6. Kryptering av trafik mellan klient och server, samt kryptering av koder som används för att arbeta med databasobjekt (lagrade procedurer, triggers, etc.)

1) Konceptet med en markör
Interaktiv SQL gör ingen skillnad mellan enrads- och flerradsfrågor. Inbäddad SQL exekverar dessa frågor på olika sätt. Enradsfrågor returnerar en rad och vi har redan täckt dem. När resultatet av en fråga är mer än en rad måste inbäddad SQL tillåta applikationen att hämta frågeresultaten rad för rad. Markörer används för detta. En markör är en variabel som är kopplad till en fråga. Dess värde är varje rad som matchar frågan. Liksom variabler måste markörer deklareras innan de kan användas. Till skillnad från vyer är markörer designade för rad-för-rad-behandling.

2) Markördeklaration

DEKLARERA [{}] [[NEJ] SKROLLA] MARKÖR [{UTAN|UTAN} HÅLL] FÖR [FÖR {LÄS ENDAST|UPPDATERA [AV ]}]

3) Nyckelord
. KÄNSLIG|INSENSITIV|ASENSITIV– ändringar i resultatuppsättningen är synliga | förbjuden (fixad med en kopia av datamängden)|DBMS själv bestämmer om en kopia ska göras (fungerar som standard).
. UTAN|UTAN HOLD– lämnar öppna | stänger markören om en COMMIT-sats påträffas.
. SKROLLA– [förhindrar] att extrahera resultatrader i slumpmässig ordning.
. ENDAST FÖR LÄS– definierar en skrivskyddad markör.
. FÖR UPPDATERING AV– blockerar endast de angivna kolumnerna från att uppdateras.

4) Deklarera en markör i SQL Server

DEKLARERA MARKÖR [LOKAL|GLOBAL] [FORWARD_ONLY|SCROLL] [STATISK|KEYSET|DYNAMISK|FAST_FORWARD] [READ_ONLY|SCROLL_LOCKS|OPTIMISTISK] FÖR [FÖR UPPDATERING [AV ]]

. STATISK– Definierar en markör som skapar en tillfällig kopia av data för användning av markören. Alla frågor mot en markör får åtkomst till den angivna temporära tabellen i tempdb-databasen, så ändringar i bastabellerna påverkar inte data som returneras av sampel för den markören, och markören i sig tillåter inte att ändringar görs.
. KEYSET– Indikerar att medlemskapet eller ordningen på rader i markören inte ändras efter att den har öppnats. En uppsättning nycklar som unikt identifierar rader är inbyggd i en tabell i tempdb-databasen som kallas keyset.
. DYNAMISK– Definierar en markör som visar alla dataändringar som gjorts på raderna i resultatuppsättningen när den här markören visas. Datavärdena, ordningen och radmedlemskapet i varje val kan variera. Alternativet ABSOLUT stöds inte av dynamiska markörer.
. SNABBSPOLA– Indikerar en FORWARD_ONLY, READ_ONLY markör för vilken prestandaoptimering är aktiverad. Alternativet FAST_FORWARD kan inte anges med alternativen SCROLL eller FOR_UPDATE.
. SCROLL_LOCKS– Indikerar att positionerade uppdateringar eller raderingar som görs via markören garanterat kommer att lyckas. SQL Server låser rader när de läses in i markören för att säkerställa att de är tillgängliga för efterföljande ändringar. Alternativet SCROLL_LOCKS kan inte specificeras med alternativet FAST_FORWARD eller STATIC.
. OPTIMISTISK– Indikerar att positionerade uppdateringar eller raderingar som görs via markören kommer att misslyckas om raden har uppdaterats sedan den lästes in i markören. SQL Server låser inte rader när de läses in i markören. Istället görs en jämförelse av värdena för tidsstämpelkolumnen (eller kontrollsummor om tabellen inte har en tidsstämpelkolumn) för att avgöra om raden har ändrats sedan den lästes in i markören. Om en rad har ändrats är dess positionerade ändring eller radering inte möjlig. Alternativet OPTIMISTISK kan inte specificeras med alternativet FAST_FORWARD.

5) Öppna markören

6) Hämta rader från markören

HÄMTA [{NÄSTA|FÖR|FÖRSTA|SIST|{ABSOLUT|RELATIV }}]
FRÅN IN I

7) Alternativ för markörpositionering
. NÄSTA|FÖR|FÖRSTA|SIST– till nästa|föregående|första|sista raden i resultatuppsättningen.
. RELATIV ±N– till en linje med en positiv eller negativ offset i förhållande till den aktuella linjen.
. ABSOLUT ±N– till en rad med ett uttryckligen angivet absolut positionsnummer från början eller slutet av markören.

Notera: SQL Server tillåter heltalsvariabeln @N istället för N.

8) Stänger markören

9) Anteckningar om markörer
. Om markören innehåller mer än en rad är det nödvändigt att organisera en slinga för att hämta data från den, och regelbundet kontrollera för att nå den sista raden.
. Till skillnad från tabeller och vyer ordnas markörrader antingen explicit med hjälp av en sektion SORTERA EFTER, eller i enlighet med de konventioner som antagits i ett visst DBMS.
. Markörer används också för att välja grupper av rader från tabeller, som kan uppdateras eller raderas en i taget.
. För att en markör ska kunna uppdateras måste den uppfylla samma kriterier som vyn, det vill säga inte innehålla avsnitt UNION, ORDER BY, GROUP BY, DISTINCT.

10) Exempel för att radera data från en markör

exec sql deklarera markör Cur1 för välj * från Kund
där Betyg
// print (@f1+’ ‘+convert(Varchar(5),@f2))
exec sql radera från kunden
där ström av Cur1; ) – Ta data att radera från markören
ej gjort:
exec sql stäng markör Cur1; — Stäng markören
utgång();

11) Exempel på höjning av provisioner

exec sql deklarera markör CurCust för välj * från Säljare
där SNum in (välj SNum från Kund där Rating=300); — Definiera markören
exec sql öppna markören CurCust; - Kör markören
while (sqlca.sqlcode==0) ( — Skapa en loop för att uppdatera data i tabellen
exec sql hämta CurCust till:Id_num, :SalesPerson, :Loc, :Comm;
exec sql update SalesPeople set Comm=Comm+.01 där aktuell
av CurCust; ) – Ta data för uppdatering från markören
exec sql stäng markör CurCust; — Stäng markören

SELECT S.Name, MAX(S.City) AS City, SUM(O.Amt) AS Amt FROM Säljare S INNER JOIN Beställningar O PÅ S.SNum=O.SNum GRUPP EFTER S.Namn BESTÄLL EFTER 2

DEKLARERA Cur1 SCROLL CURSOR FÖR SELECT S.Name, MAX(S.City) AS City, SUM(O.Amt) AS Amt FROM SalesPeople S INNER JOIN Orders O ON S.SNum=O.SNum GROUP BY S.Name BESTÄLL EFTER 2
ÖPPEN Cur1
HÄMTA NÄSTA FRÅN Cur1
WHILE @@FETCH_STATUS=0
BÖRJA
HÄMTA NÄSTA FRÅN Cur1
SLUTET
STÄNG Cur1
AVDELA Cur1