Kurzorok és hurkok használata a Transact-SQL-ben. Kurzorok a MySQL tárolt eljárásokban Kurzorok az sql szerverben

A DECLARE CURSOR parancs lehetővé teszi a rekordok lekérését egy táblázatból soronként manipulálás céljából. Ez lehetővé teszi a soronkénti feldolgozást az SQL által végzett hagyományos adatkészlet-feldolgozás helyett.

Legelső közelítésként a következő lépéseket használjuk a kurzorral való munka során.

A kurzor a DECLARE paranccsal jön létre. A kurzor az OPEN paranccsal nyílik meg.

A kurzorral végzett műveletek a FETCH paranccsal hajthatók végre. A kurzort a CLOSE paranccsal zárjuk be.

A DECLARE CURSOR parancs egy SELECT utasítást ad meg. A SELECT utasítás által visszaadott minden sor külön-külön lekérhető és feldolgozható. A következő Oracle-példa egy kurzort deklarál egy deklarációs blokkban számos más változóval együtt. Ezt követően a következő BEGIN...END mondatban megnyílik a kurzor, kiválasztunk belőle, majd bezárjuk a kurzort.

CURSOR title_price_cursor IS SELECT title, price FROM titles

AHOL az ár NEM NULLA; title_price_val title_price_cursor ROWTYPE; új_ár SZÁM(10,2);

OPEN title_price_Cursor;

FELTÉTELEK cím_ár_cur-sor INTO cím_ár_értéke;

new_price:= "title_price_val.price" * 1,25 INSERT INTO new_title_price VALUES

(title_price_val.title, new_price) CLOSE title_price_cursor; VÉGE;

Mivel ez a példa PL/SQL-t használ, ebben a könyvben nem magyarázzuk meg a kód nagy részét. A DECLARE blokk azonban egyértelműen mutatja a kurzor deklarációját. Egy végrehajtható PL/SQL blokkban a kurzor inicializálása az OPEN paranccsal történik, az értékek lekérése a FETCH paranccsal történik, végül a kurzort a CLOSE paranccsal zárjuk be.

A SELECT utasítás a kurzor alapja, ezért célszerű alaposan tesztelni, mielőtt belefoglalnánk a DECLARE CURSOR utasításba. A SELECT utasítás működhet az alapul szolgáló táblán vagy nézeten. Ezért a csak olvasható kurzorok nem frissíthető nézetekkel is működhetnek. A SELECT utasítás tartalmazhat olyan záradékokat, mint például ORDER BY, GROUP BY és HAVING, amennyiben ezek a záradékok nem frissítik a forrástáblát. Ha a kurzor FOR UPDATE-ként van definiálva, akkor javasolt az ilyen záradékok eltávolítása a SELECT utasításból.

A helyi kurzorokat gyakran használják a tárolt eljárások kimeneti paramétereiként. Ezért megadhat és feltölthet kurzort egy tárolt eljárásban, és átadhatja az azt meghívó kötegelt feladatnak vagy tárolt eljárásnak.

A következő egyszerű DB2 példában deklarálunk egy kurzort, amely megkeresi a részlegszámokat, részlegneveket és menedzserszámokat az admin_group "XO1" csoportban.

DECLARE dept_cursor CURSOR

FOR SELECT részleg_nbr., részleg_neve, igazgató_nbr

WHERE admin_group="X01"

ORDER BY d"ept_name ASC, dept_nbr DESC, mgr_nbr DESC;

A következő Microsoft SQL Server példa deklarál és megnyit egy kurzort a kiadói táblához. A kurzor kiválasztja az első rekordot, amely megfelel a SELECT utasításnak a közzétevők táblájából, és beszúrja egy másik táblába. Ezután továbblép a következő rekordra, majd a következőre, amíg az összes rekordot fel nem dolgozták. Végül a kurzor bezárul, és a memória felszabadul (a DEALLOCATE parancs csak a Microsoft SQL Serverben használatos).

DECLARE @publisher_name VARCHAR(20)

DECLARE pub_cursor CURSOR FOR SELECT pub_name FROM publishers WHERE ország "USA"

FETCH NEXT FROM pub_cursor INTO publisher_name

WHILE @s>FETCH_STATUS=0

INSERT INTO Foreign_publishers VALUES("j>kiadó_neve)

pub_cursor bezárása DEALLOCATE pub_cursor

Ebben a példában láthatja, hogy a kurzor a rekordok között mozog. (Ez a példa csak az ötlet bemutatására szolgál, mivel a valóságban létezik A legjobb mód megoldás erre a problémára, nevezetesen az INSERT, SELECT utasítás.)

ARRA VONATKOZIK: SQL Server (2008 óta)Base SQL adatok Azure SQL Data WarehouseParallel Data Warehouse

Meghatározza a Transact-SQL kiszolgáló kurzor attribútumait, például a nézet tulajdonságait és a kurzor működéséhez használt eredménykészlet felépítéséhez használt lekérdezést. A DECLARE CURSOR utasítás egyaránt támogatja az ISO szabványú szintaxist és a Transact-SQL nyelvi kiterjesztéskészletet használó szintaxist.

ISO szintaxis DECLARE cursor_name [ Érzéketlen ] [ SCROLL ] KURSZOR A select_utasításhoz [ FOR ( CSAK OLVASÁS | FRISSÍTÉS [ OF oszlopnév [ ,...n ] ] ) ] [;] Transact-SQL kiterjesztett szintaxis DECLARE cursor_name CURSOR [ HELYI | GLOBÁLIS ] [ FORWARD_ONLY | SCROLL ] [ STATIKUS | KEYSET | DINAMIKUS | FAST_FORWARD ] [ CSAK OLVASÁS | SCROLL_LOCKS | OPTIMISZTIKAI ] [ TYPE_WARNING ] FOR select_utasítás [ FOR UPDATE [ OF oszlopnév [ ,...n ] ] ] [;]

kurzor_neve
kurzor_neve

ÉRZÉKETLEN
tempdb; így az alapul szolgáló táblák változásai nem tükröződnek a kurzor által kiválasztott adatokban, és ez a kurzor nem módosítható. ISO szintaxis használatakor, hacsak nincs megadva az ÉRZÉKENY opció, az alaptáblázatok véglegesített frissítései és törlései megjelennek a következő kijelölésekben.

TEKERCS
Azt jelzi, hogy az összes mintavételi lehetőség elérhető (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE). Ha az ISO DECLARE CURSOR utasítás nem ad meg SCROLL beállítást, akkor csak a NEXT fetch beállítás támogatott. A SCROLL opció nem adható meg a FAST_FORWARD opcióval.

select_ Statement
Szabványos SELECT utasítás, amely megadja a kurzor eredményhalmazát. A FOR BROWSE és INTO kulcsszavak nem használhatók select_ Statement kurzor deklaráció.

select_ Statementütközik a kért típusú kurzorral.

CSAK OLVASHATÓ

Frissítés ]
oszlop_neve [, .. .n] van megadva, csak a felsorolt ​​oszlopok engednek változtatásokat. Ha az UPDATE utasítást oszloplista nélkül használja, akkor a frissítés minden oszlopra lehetséges.

kurzor_neve
Az adott kiszolgáló kurzorának Transact-SQL neve. kurzor_neve be kell tartania az azonosítókra vonatkozó szabályokat.

HELYI
Azt jelzi, hogy a kurzor helyi ahhoz a csomaghoz, tárolt eljáráshoz vagy eseményindítóhoz, amelyben létrehozták. A kurzor neve csak ezen a területen érvényes. A kurzorra a csomag helyi változói, tárolt eljárások, triggerek vagy a tárolt eljárás kimeneti paraméterei hivatkozhatnak. Az OUTPUT paraméter egy helyi kurzor átadására szolgál a hívó csomagnak, tárolt eljárásnak vagy triggernek, amely ezután hozzárendelheti a paramétert egy kurzorváltozóhoz, hogy a tárolt eljárás befejezése után hozzáférjen a kurzorhoz. A kurzor implicit módon felszabadul, amikor a köteg, a tárolt eljárás vagy az eseményindító befejezi a végrehajtást, kivéve, ha a kurzort átadták az OUTPUT paraméternek. Ha a kurzort az OUTPUT paraméterhez adták át, akkor a kurzor elengedi, amikor az összes rá hivatkozó változó felszabadul, vagy amikor kilép a hatókörből.

GLOBÁLIS
Azt jelzi, hogy a kurzor globális a kapcsolathoz. A kurzor nevét a kapcsolaton futó bármely tárolt eljárás vagy csomag használhatja. A kurzor implicit módon csak akkor szabadul fel, ha a kapcsolat megszakad.

FORWARD_ONLY
Megadja, hogy a kurzor csak az első sortól az utolsóig látható. Csak a FETCH NEXT lekérés opció támogatott. Ha a FORWARD_ONLY a STATIC, KEYSET vagy DYNAMIC kulcsszavak nélkül van megadva, a kurzor DINAMIKUS kurzorként viselkedik. Ha sem a FORWARD_ONLY, sem a SCROLL argumentum nincs megadva, az alapértelmezett a FORWARD_ONLY argumentum, kivéve, ha a STATIC, KEYSET vagy DYNAMIC kulcsszavak jelen vannak. A STATIC, KEYSET és DYNAMIC kurzorok alapértelmezett értéke SCROLL. Ellentétben az olyan adatbázis API-kkal, mint az ODBC és az ADO, a FORWARD_ONLY módot a következő Transact-SQL kurzorok támogatják: STATIC, KEYSET és DYNAMIC.

STATIKUS
Meghatároz egy kurzort, amely ideiglenes másolatot hoz létre az adatokról a kurzor általi használatra. A kurzor minden lekérdezése hozzáfér a megadott ideiglenes táblához tempdb; így az alapul szolgáló táblák változásai nem tükröződnek a kurzor által kiválasztott adatokban, és ez a kurzor nem módosítható.

KEYSET
Azt jelzi, hogy a kurzorban lévő sorok tagsága vagy sorrendje nem változik a megnyitáskor. A sorokat egyedileg azonosító kulcskészlet be van építve a táblázatba tempdb hívott kulcsok.

Az alaptáblázatok nem kulcsértékeinek a kurzor tulajdonosa által végrehajtott vagy más felhasználók által végrehajtott módosításai akkor jelennek meg, amikor a kurzor tulajdonosa megtekinti azokat. A többi felhasználó által végrehajtott változtatások nem tükröződnek (a Transact-SQL szerver kurzorral nem hajthatók végre a módosítások). Ha egy sort törölnek, a sorok lekérésére tett kísérlet a @@FETCH_STATUS -2 értéket adja vissza. A kurzor határain átnyúló kulcsértékek frissítése hasonló a régi sor törléséhez, majd egy új sor beszúrásához. Az új értékeket tartalmazó sor nem látható, és megpróbálja lekérni a régi értékeket tartalmazó sort @@FETCH_STATUS -2. A frissítések azonnal láthatók, ha a WHERE CURRENT OF záradék használatával a kurzoron keresztül történik.

DINAMIKUS
Meghatároz egy kurzort, amely megjeleníti a kurzor megtekintése közben az eredményhalmaz soraiban végrehajtott összes adatmódosítást. Az adatértékek, a sorrend és a sortagság az egyes kijelölésekben változhat. Az ABSZOLÚT kiválasztási opciót a dinamikus kurzorok nem támogatják.

ELŐREPÖRGETÉS
Olyan FORWARD_ONLY, READ_ONLY kurzort jelez, amelynél engedélyezve van a teljesítményoptimalizálás. A FAST_FORWARD opció nem adható meg a SCROLL vagy FOR_UPDATE opciókkal.

CSAK OLVASHATÓ
Megakadályozza a kurzoron keresztül végrehajtott változtatásokat. A WHERE CURRENT OF záradék nem hivatkozhat kurzorra az UPDATE vagy DELETE utasításban. Ez a beállítás elsőbbséget élvez az alapértelmezett kurzorfrissítési funkcióval szemben.

SCROLL_LOCKS
Azt jelzi, hogy a kurzorral végzett elhelyezett frissítések vagy törlések garantáltan sikeresek lesznek. Az SQL Server zárolja a sorokat a kurzorba való beolvasásukkor, hogy biztosítsa, hogy ezek a sorok elérhetők legyenek a későbbi módosításokhoz. A SCROLL_LOCKS beállítás nem adható meg a FAST_FORWARD vagy a STATIC opcióval.

OPTIMISTA
Megadja, hogy a kurzorral végrehajtott pozicionált frissítések vagy törlések sikertelenek legyenek, ha a sor a kurzorba való beolvasás óta frissül. Az SQL Server nem zárolja a sorokat, amikor beolvassák a kurzorba. Ehelyett összehasonlításokat használnak időbélyeg oszlopértékek ill ellenőrző összegeket, ha nem a táblázatban időbélyeg oszlopot annak meghatározására, hogy a sor megváltozott-e a kurzorba való beolvasás óta. Ha a sort módosították, a pozicionált frissítési vagy törlési kísérletek sikertelenek lesznek. Az OPTIMISTIC beállítás nem adható meg a FAST_FORWARD opcióval.

TYPE_WARNING
Megadja, hogy a rendszer figyelmeztetést küld az ügyfélnek, ha a kurzor implicit módon az egyik kért típusról a másikra konvertálódik.

select_ Statement
Szabványos SELECT utasítás, amely megadja a kurzor eredményhalmazát. A COMPUTE, COMPUTE BY, FOR BROWSE és INTO kulcsszavak nem használhatók select_ Statement kurzor deklaráció.

Az SQL Server implicit módon átalakítja a kurzort egy másik típusra, ha a záradékok benne vannak select_ Statementütközik a kért típusú kurzorral. További információkért lásd az Implicit kurzorkonverziók című részt.

FRISSÍTÉSHEZ ]
Meghatározza a kurzor frissítendő oszlopait. Ha OF oszlop_neve [, ... n] van megadva, csak a felsorolt ​​oszlopok teszik lehetővé a változtatásokat. Ha az UPDATE utasítást oszloplista nélkül használja, akkor a frissítés minden oszlopban lehetséges, hacsak nincs megadva a READ_ONLY párhuzamossági beállítás.

A DECLARE CURSOR utasítás meghatározza a Transact-SQL kiszolgáló kurzor attribútumait, például a nézet tulajdonságait és a lekérdezést, amelyet a kurzor működéséhez használt eredménykészlet felépítéséhez használnak. Az OPEN utasítás kitölti az eredményhalmazt, a FETCH utasítás pedig egy sort ad vissza belőle. A CLOSE utasítás törli a kurzorhoz tartozó aktuális eredménykészletet. A DEALLOCATE utasítás felszabadítja a kurzor által használt erőforrásokat.

A DECLARE CURSOR utasítás első formája ISO szintaxist használ a kurzorparaméterek megadásához. A DECLARE CURSOR utasítás második formája a Transact-SQL nyelv kiterjesztéseit használja, amelyek lehetővé teszik, hogy a kurzorokat ugyanazokkal a típusokkal definiálja, mint az adatbázis API-k (például ODBC és ADO) kurzorfunkcióiban.

Ez a két forma nem keverhető össze. Ha a CURSOR kulcsszó előtt megadja a SCROLL-t vagy kihagyja a kulcsszavakat, nem használhat kulcsszavakat a CURSOR között és select_ Statement kulcsszavakat. Kulcsszavak megadásakor a CURSOR között, valamint a számára select_ Statement kulcsszavakat, nem adhatja meg a CURSOR kulcsszó előtt a SCROLL vagy az INSENSITIVE értéket.

Ha Transact-SQL szintaxist használ a DECLARE CURSOR utasításhoz, és nem adja meg a READ_ONLY, OPTIMISTIC vagy SCROLL_LOCKS beállításokat, a rendszer a következő alapértelmezett értéket feltételezi.

    Ha a SELECT utasítás nem támogatja a frissítéseket (vagy nem rendelkezik megfelelő jogosultságokkal, vagy olyan távoli táblákat ér el, amelyek nem támogatják a frissítéseket stb.), a kurzor READ_ONLY értékre áll.

    A STATIC és a FAST_FORWARD kurzorok alapértelmezett értéke READ_ONLY.

    A DYNAMIC és a KEYSET kurzorok alapértelmezés szerint OPTIMISTICS.

A kurzorokra csak más Transact-SQL utasítások hivatkozhatnak. Az adatbázis API-függvényei nem hivatkozhatnak kurzorokra. Például a kurzor deklarálása után az OLE DB, ODBC vagy ADO függvények és metódusok nem hivatkozhatnak a nevére. A kurzorsorok nem választhatók ki a megfelelő API-függvényekkel és metódusokkal; Erre a célra Transact-SQL FETCH utasításokat kell használnia.

A következő tárolt eljárások használhatók a kurzor tulajdonságainak meghatározására, miután deklaráltuk.

A változók részeként használhatók select_ Statement, amelyben a kurzor deklarálva van. A kurzorváltozók értéke nem változik a deklarálás után.

Alapértelmezés szerint a CURSOR DECLARE engedélye minden olyan felhasználó számára biztosított, aki SELECT engedéllyel rendelkezik a kurzor által használt nézetekhez, táblázatokhoz és oszlopokhoz.

Nem használhat kurzorokat vagy triggereket egy fürtözött oszloptár-indexszel rendelkező táblán. Ez a korlátozás nem vonatkozik a nem fürtözött indexekre; Használhat kurzorokat és triggereket egy nem fürtözött oszloptároló indexű táblán.

V. Egyszerű kurzor és szintaxis használata

A kurzor megnyitásakor létrehozott eredményhalmaz a táblázat összes sorát és oszlopát tartalmazza. Ez a kurzor frissíthető, az összes frissítés és törlés megjelenik a kurzor kiválasztásában. A FETCH``NEXT csak azért lesz letöltve, mert a SCROLL paraméter nincs megadva.

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

B. Beágyazott kurzorok használata jelentés megjelenítéséhez

A következő példa beágyazott kurzorokat használ egy összetett jelentés megjelenítéséhez. Minden szolgáltatóhoz egy belső kurzor van deklarálva.

SET NOCOUNT ON ; DECLARE @vendor_id int , @vendor_name nvarchar ( 50 ), @message varchar ( 80 ), @product nvarchar ( 50 ); NYOMTATÁS" -------- Szállítói termékjelentés --------"; DECLARE vendor_cursor CURSOR FOR SELECT VendorID, Name FROM Purchasing.Vendor WHERE PreferredVendorStatus = 1 RENDELÉS A Szállítóazonosító szerint; vendor_cursor MEGNYITÁSA FETCH NEXT FROM vendor_cursor INTO @vendor_id, @vendor_name WHILE @@FETCH_STATUS = 0 BEÁLLÍTÁS NYOMTATÁS " " KIVÁLASZTÁS @üzenet = "----- Termékek a szállítótól: "+ @vendor_name PRINT @üzenet -- Belső kurzor alapú deklarálása -- a vendor_id-n a külső kurzorból. A termék_kurzorának DECLARE FOR SELECT v.Name FROM Purchasing.ProductVendor pv, Production.Product v WHERE pv.ProductID = v.ProductID AND pv.VendorID = @vendor_id -- Változó érték a külső kurzorból OPEN product_cursor FETCH NEXT FROM FROM product_cursor INTO @product IF @@FETCH_STATUS<>0 NYOMTATÁS "<>" WHILE @@FETCH_STATUS = 0 BEGIN KIVÁLASZTÁS @message = " " + @termék NYOMTATÁSA @üzenet LETÖLTÉS A termék_kurzor KÖVETKEZŐBŐL A @termékbe VÉGE CLOSE product_cursor FELTÉTELEZÉS product_cursor -- Szerezze meg a következő szállítót. ELKÉRÉS A KÖVETKEZŐEN A vendor_cursor INTO @vendor_id, @vendor_id END CLOSE vendor_cursor; DEALLOCATE vendor_cursor;


A kurzor egy hivatkozás a környezeti memóriaterületre. Az SQL programozási nyelv egyes megvalósításaiban (Oracle, Microsoft SQL Server) - a lekérdezés végrehajtásakor kapott eredménykészlet és a hozzá tartozó aktuális rekordmutató. Azt mondanám, hogy a kurzor egy virtuális tábla, amely egy alternatív adattárolást jelent. Ebben az esetben a kurzor lehetővé teszi az adatok elérését, mintha egy szabályos tömb adatai lennének.
A kurzorokat tárolt eljárásokban használják. Elég az elméletből, nézzünk egy példát:
Van egy adatbázisunk (az adatbázis egy kicsit nem jó, ez az egyik az enyém laboratóriumi munka, de adatbázis tanárunk ragaszkodott egy ilyen szerkezethez)
/*Bank információ*/
"bank" TÁBLÁZAT LÉTREHOZÁSA (

`BankName` VARCHAR (50) COLLATE utf8_bin NOT NULL ALAPÉRTELMEZETT "" ,


PRIMER KULCS ("BankId")

)ENGINE=InnoDB
KARAKTER BEÁLLÍTÁS "utf8" COLLATE "utf8_bin" ;
/*adatok a betétekről */
TÁBLÁZAT LÉTREHOZÁSA "banki elosztás" (
`BankId` INTEGER (11) NEM NULL ,
"Persent" INTEGER (11) DEFAULT NULL ,
`ContributeAmount` DECIMAL (10,0) NEM NULL ,
`ClientId` INTEGER (11) NEM NULL ,
PRIMARY KEY(`BankId`, `ClientId`),
KEY `BankId` (`BankId`),
KEY `ClientId` (`ClientId`),
CONSTRAINT `bankdistribution_fk` FOREIGN KEY (`BankId`) REFERENCIÁK `bank` (`BankId`),
CONSTRAINT `bankdistribution_fk1` IDEGEN KULCS (`ClientId`) HIVATKOZÁS `kliens` (`ClientId`)
)ENGINE=InnoDB
/*adatok a befektetőkről*/
`kliens` TÁBLÁZAT LÉTREHOZÁSA (
`ClientId` INTEGER (3) NEM NULL AUTO_INCREMENT,
`CreditCardId` BIGINT(10) NEM NULL ,
`Vezetéknév` VARCHAR (50) COLATE utf8_bin NOT NULL ALAPÉRTELMEZETT "" ,
`Név` VARCHAR (50) COLATE utf8_bin NOT NULL ALAPÉRTELMEZETT "" ,
`FirstName` VARCHAR (50) COLLATE utf8_bin NOT NULL ALAPÉRTELMEZETT "" ,
`Telefon` VARCHAR (50) COLATE utf8_bin NOT NULL ALAPÉRTELMEZETT "" ,
`Cím` VARCHAR (50) COLATE utf8_bin NOT NULL ALAPÉRTELMEZETT "" ,
"SafeId" INTEGER (5) NEM NULL ,
PRIMARY KEY(`ClientId`, `CreditCardId`),
KEY `ClientId` (`ClientId`)

)ENGINE=InnoDB
AUTO_INCREMENT=11 KARAKTERBEÁLLÍTÁS "utf8" CSOMAGOLÁS "utf8_bin"

Tegyük fel, hogy sorra kell fogadnunk minden bankot, és végre kell hajtanunk vele néhány műveletet, ebben segíthet a következő lekérdezés

Válassza ki a `bankot'
. Így a LIMIT WE NEED_RECORD NUMBER, 1 használatával sorra kinyerjük az egyes rekordokat egy ciklusban a banktáblából, és végrehajtjuk vele a szükséges műveleteket, miközben a WE NEED_RECORD NUMBER értékét 1-gyel növeljük. Most ugyanezt tesszük, de kurzor segítségével
Kezdődik
/* változók, amelyekből adatokat nyerünk */
A vBankId egész szám deklarálása ;
vBankName deklarálása VARCHAR(50);
vCím deklarálása VARCHAR(50);
A vPhone VARCHAR bejelentése (50);
/* hadler változó - a*/
Kész egész szám deklarálása alapértelmezett 0;
/*Kurzor deklaráció*/
Bankkurzor kurzor kijelölése a következőhöz: Select `bank`.`BankId`,`bank`.`BankName`,`bank`.`Cím`,`bank`.`Telefon, FROM `bank` ahol 1;
/*KEZELŐ célja, amelyet alább ismertetünk*/
DECLARE CONTINUE HANDLER FOR SQLSTATE "02000" SET done=1;
/* kurzor megnyitása */
Nyissa meg a BankCursort;
/*adatok lekérése*/
WHILE done = 0 DO

megtesszük a szükséges lépéseket
END WHILE ;
/*kurzor bezárása*/
BankCursor bezárása;
VÉGE ;

* Ezt a forráskódot a Source Code Highlighter kiemelte.

Hiba: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)

Üzenet: Nincs adat – nulla sor lekérve, kiválasztva vagy feldolgozva

SQLSTATE: A 02000 akkor aktiválódik, amikor eléri a kurzor végét, vagy amikor a kijelölés vagy frissítés üres karakterláncot ad vissza.

A következő sorban deklaráltuk a kurzort DECLARE kurzornév CURSOR FOR select_statement;
Nyissa meg a kurzort Open cursor_name;
Ezután, amíg el nem érjük a kurzor végét (WHILE done = 0 DO), kinyerjük az adatokat és feldolgozzuk.
A tárolt eljárásból való kilépés előtt be kell zárnia a kurzort. kurzornév bezárása;

Nem tűnik bonyolultnak. Az SQLSTATE "02000"-hez azonban sok buktató van.

WHILE done = 0 DO
BANKKUROR BESZERZÉSE vBankId,vBankName,vAddress,vPhone;

Válassza ki (ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution, ahol BankId = vBankId limit 1;
csinálunk néhány műveletet
END WHILE ;

* Ezt a forráskódot a Source Code Highlighter kiemelte.


Szintaktikai szempontból minden rendben van és helyes. De logikai szempontból nem. Előfordulhat, hogy a betétesek nem nyitottak számlát valamelyik bankban, akkor Select (ContributeAmount) INTO vContributeAmountSUM FROM banki disztribúció esetén ahol BankId = vBankId limit 1; SQLSTATE: A 02000 aktiválódik, a done változó 1-re lesz állítva, és a while ciklus korábban ér véget, mint vártuk. Ez elkerülhető a következőkkel
WHILE done = 0 DO
BANKKUROR BESZERZÉSE vBankId,vBankName,vAddress,vPhone;
/* kivonat a bank számára bármely betét összegéről */


if (vContributeAmountSUM > 0) akkor
/* kivonat a bank számára bármely betét összegéről */

vége if ;
csinálunk néhány műveletet
END WHILE ;

* Ezt a forráskódot a Source Code Highlighter kiemelte.


Az első kéréssel ellenőriztük, hogy vannak-e hozzájárulások (ha nincs, akkor vContributeAmountSUM == 0), és csak ha van, akkor kérjük le az adatokat.

Most tegyük fel, hogy minden ügyfélnél el kell távolítanunk a különböző bankokban lévő számlák teljes összegét
ClientSummCursor Kurzor deklarálása az összeg kiválasztásához

Adja meg a ClientSummCursor kurzort a Select sum (`bankdistribution`.`ContributeAmount`), `bankdistribution`.`ClientId` FROM `bankdistribution` belső csatlakozási klienshez (client.ClientId = bankdistribution.`ClientId`), ahol 1 csoport:`bankdistribution. `ClientId`;

Nyissa meg a ClientSummCursort;
WHILE done = 0 DO
BANKKUROR BESZERZÉSE vBankId,vBankName,vAddress,vPhone;
/* kivonat a bank számára bármely betét összegéről */
Válassza a Count(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution lehetőséget, ahol BankId = vBankId limit 1;
/* ellenőrizze, hogy valóban vannak-e betétek ebben a bankban */
if (vContributeAmountSUM > 0) akkor
/* kivonat a bank számára bármely betét összegéről */
Válassza a ContributeAmount INTO vContributeAmountSUM FROM bankdistribution lehetőséget, ahol BankId = vBankId limit 1;
vége if ;


csinálunk néhány műveletet.
END WHILE ;

* Ezt a forráskódot a Source Code Highlighter kiemelte.

Ugyanez a helyzet akkor is előfordulhat, ha a ClientSummCursor kurzorban lévő adatok korábban érnek véget, mint a BankCursorban, az SQLSTATE: 02000 aktiválódik, a done változó 1-re van állítva, és a while ciklus korábban ér véget, mint azt vártuk. Ez elkerülhető a következőkkel

Nyissa meg a ClientSummCursort;
WHILE done = 0 DO
BANKKUROR BESZERZÉSE vBankId,vBankName,vAddress,vPhone;
/* kivonat a bank számára bármely betét összegéről */
Válassza a Count(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution lehetőséget, ahol BankId = vBankId limit 1;
/* ellenőrizze, hogy valóban vannak-e betétek ebben a bankban */
if (vContributeAmountSUM > 0) akkor
/* kivonat a bank számára bármely betét összegéről */
Válassza a ContributeAmount INTO vContributeAmountSUM FROM bankdistribution lehetőséget, ahol BankId = vBankId limit 1;
vége if ;
/* mielőtt kivonja az adatokat a második kurzorból, emlékezzen az sqlstate állapotra */
SET old_status = kész;
/* kivonja a szükséges adatokat */
FETCH ClientSummCursor INTO vSum,vClientId;
/* ellenőrizze, hogy az adatok lekérése megtörtént-e, és hogy az sqlstate 0200 nem sikerült-e */
ha (kész = 0) akkor
csinálunk néhány műveletet.
vége if ;
/* a while vége előtt állítsa vissza a done változó értékét */
set done = régi_állapot;
END WHILE ;

* Ezt a forráskódot a Source Code Highlighter kiemelte.

Köszönöm mindenkinek, aki idáig elolvasta, remélem hasznos lesz valakinek.

A kurzor megvalósítása egy adatbázisban egy Java osztályhoz hasonlít, amely adatkészlettel és módszerekkel rendelkezik a feldolgozásához. Ahol sql kurzor szabályos tömbként használja az adatokat. A kurzorok triggerekben, tárolt eljárásokban és függvényekben használhatók.

Az SQL szabványnak megfelelően a kurzorokkal végzett munka során a következő alapvető műveleteket hajtják végre:

  • kurzor deklaráció;
  • kurzor megnyitása adatolvasással;
  • soronkénti mintavételezés az adatokból a kurzorból;
  • sor adatainak megváltoztatása a kurzor segítségével;
  • a kurzor bezárása, amely után elérhetetlenné válik;
  • a kurzor elengedése, azaz. kurzor eltávolítása a memóriából, mert a bezárása nem feltétlenül szabadítja fel a hozzá tartozó memóriát.

Különböző megvalósításokban a definíció kurzor lehetnek eltérések. Például néha szükség van a kurzor számára lefoglalt memória kifejezetten felszabadítására. A kurzor felszabadítása után a hozzá tartozó memória is felszabadul. Ez lehetővé teszi a kurzor nevének újrafelhasználását. Más megvalósításokban a kurzor bezárásakor a memória implicit módon felszabadul.

Bizonyos esetekben nem nélkülözheti a kurzort. Azonban ha lehetséges, kerülje a kurzor használatát, és dolgozzon szabványos adatfeldolgozási parancsokkal: SELECT, UPDATE, INSERT, DELETE. Ennek oka az a tény, hogy a kurzorok nem teszik lehetővé a teljes adatmennyiségen a módosítási műveleteket, és az adatfeldolgozási műveletek kurzorral történő végrehajtásának sebessége észrevehetően alacsonyabb, mint szabvány azt jelenti SQL.

Ha egy program képes megváltoztatni a kurzorba betöltött adatokat, akkor azt módosíthatónak nevezzük. Amikor kurzorokról beszélünk, ne feledkezzünk meg a tranzakciók elkülönítéséről. Az egyik felhasználó egy kurzorral módosít egy rekordot, míg egy másik felhasználó a saját kurzorával olvassa be azt. Ezenkívül megváltoztathatja ugyanazt a rekordot, ami szükségessé teszi az adatok integritásának megőrzését.

Kurzor deklarálása

A kurzorokat használat előtt deklarálni kell. Az SQL szabvány a következő szintaxist használja a kurzor létrehozásához:

A kurzor_neve kurzor deklarálása a select_utasításhoz ])]

Ez a kifejezés egy kurzort deklarál deklarálja a kurzort a "kurzor_neve" névvel.

ÉRZÉKETLEN statikus kurzor jön létre, amely nem teszi lehetővé a változtatások végrehajtását. Ezenkívül a többi felhasználó által végrehajtott módosítások nem jelennek meg. Ha az INSENSITIVE kulcsszó hiányzik, akkor dinamikus kurzor jön létre.

Kulcsszó használatakor TEKERCS a létrehozott kurzor tetszőleges irányba görgethető, így bármilyen kiválasztási parancsot alkalmazhat. Ha ezt az argumentumot kihagyjuk, akkor a kurzor szekvenciális lesz, azaz. megtekintése csak egy irányban lesz lehetséges – az elejétől a végéig.

Kifejezés select_ Statement olyan struktúrát jelöl, amely az információk olvasására szolgál, mint például a select ... from ... . Nem tartalmazhatja az operátort -ba, mivel a kurzornak saját operátora van elhozni változók kurzoradatokkal való kitöltéséhez.

Egy argumentum megadásakor CSAK OLVASÁSRA csak olvasható kurzor jön létre, és az adatok módosítása nem engedélyezett. A dinamikus kurzor csak olvasható kurzorként deklarálható, lehetővé téve egy másik felhasználó által végrehajtott módosítások megjelenítését.

Kurzor létrehozása argumentummal FRISSÍTÉSHEZ lehetővé teszi a kurzorban lévő adatok módosítását a megadott oszlopokban vagy argumentum hiányában OF oszlop_neve, minden oszlopban.

Egy szubrutinban több kurzort is deklarálhat. De minden kurzornak egyedi névvel kell rendelkeznie. A kurzor megnyitásához az operátort kell használni nyisd ki amely megnyitja az előzőleg deklarált kurzort:

Kurzor nyitva

Az SQL a következő szintaxist határozza meg a kurzor megnyitásához: "cursor open":

kurzornév megnyitása;

Adatok lekérése a kurzorból, kurzorlekérés

Az adatok kurzorból néhány változóba történő beolvasásának szintaxisa a következő:

A kurzornév lekérése a var_name [, var_name] fájlba ...;

Operátor elhozni után található változókba választja ki a nyitott kurzoradatokat -baés a kurzort a következő pozícióba mozgatja.

A kurzor bezárása

Operátor Bezárás bezárja a kurzort. Ha az operátor nincs kifejezetten megadva, a kurzor automatikusan bezárul a megfelelő programblokk bezárásakor.

kurzornév bezárása;

A bezárás után a kurzor elérhetetlenné válik. Bezáráskor a kurzor futása közben telepített összes zár feloldódik. Csak a nyitott kurzorok zárhatók be. A bezárt, de fel nem engedett kurzor újra megnyitható. A megnyitatlan kurzor bezárása nem megengedett.

Minden DBMS-nek megvannak a maga sajátosságai a kurzor használatára vonatkozóan.

A kurzorok használatának jellemzői az Oracle-ben

A PL/SQL-ben négy kurzorattribútum található %MEGTALÁLT, %NEM TALÁLHATÓ, %NYITVA VANÉs %ROWCOUNT. A kurzorattribútumok a %TYPE és a %ROWTYPE operátorokhoz hasonlóan a kurzor nevétől jobbra vannak deklarálva.

%FOUND attribútum

%NOTFOUND attribútum

A %NOTFOUND attribútum a %FOUND pontos ellentéte.

%ISOPEN attribútum

Az %ISOPEN attribútum csak azt jelzi, hogy a kurzor nyitva van-e vagy sem.

%ROWCOUNT attribútum

Tulajdonság %ROWCOUNT egy numerikus attribútum, amely a kurzor által egy adott időpontban beolvasott sorok számát adja vissza.

Példa egy SQL kurzorra egy Oracle DBMS-ben

A v_id managers.id deklarálása %TYPE; v_name managers.name%TYPE; v_comm managers.comm%TYPE; crs kurzor az id, név, összeg(comm) mint komm kiválasztásához a vezetőktől, ahol a "2014-11-01" és "2014-11-30" közötti adatok azonosító, név szerint csoportosítják; start open crs; ciklus EXIT WHEN crs%NOTFOUND; KERESÉS KRS-t a v_id, v_name, v_comm fájlba; beszúrni a bonus(id, name, comm) értékekbe (crs.id, crs.name, crs.comm); vég hurok; elkövetni; crs bezárása; vége;

A kurzorok használatának jellemzői az SQL szerverben

Az MSSQL-ben használt kurzorok lehetnek szekvenciálisak vagy görgethetők. A szekvenciális lehetővé teszi az adatok csak egy irányba történő kiválasztását - az elejétől a végéig. A görgethető kurzorok lehetővé teszik a mozgást mindkét irányban, és lehetővé teszik, hogy tetszőleges sorra ugorjon a kurzor eredménykészletében.

Az SQL Server támogatja a statikus, dinamikus, szekvenciális és kulcskészlet-vezérelt kurzorokat.

A statikus kurzortervben az információ egy adott időpontban pillanatfelvételként kerül tárolásra. Ezért a másik felhasználó által az adatbázisban végrehajtott módosítások nem láthatók. A kurzor megnyitása közben a szerver zárolja a teljes eredménykészletben szereplő összes sort. A statikus kurzor a létrehozás után nem változik, és mindig azt az adatkészletet jeleníti meg, amely a megnyitásakor létezett. Ha más felhasználók megváltoztatják a kurzorban szereplő adatokat a forrástáblázatban, az nem lesz hatással a statikus kurzorra. A statikus kurzoron nem lehet változtatni, ezért mindig csak olvasható módban nyílik meg.

A dinamikus kurzor további hálózati többletterhelést és szoftvererőforrást igényel. Dinamikus kurzorok használatakor az adatok teljes másolata nem jön létre, hanem a forrástáblázatokból történő kijelölés csak akkor történik meg, ha a felhasználó hozzáfér bizonyos adatokhoz. A lekérés során a szerver zárolja a sorokat, és a felhasználó által a kurzor teljes eredménykészletén végrehajtott változtatások láthatók lesznek a kurzorban. Ha azonban a kurzor lekérte az adatokat, a másik felhasználó által végrehajtott módosítások többé nem jelennek meg a kurzorban.

A billentyűkészlettel vezérelt kurzor statikus és dinamikus tulajdonságokkal rendelkezik. A rekordokat a mintavételkor azonosítják, és így nyomon követik a változásokat. Ez a fajta kurzor akkor hasznos, ha visszafelé görgetést hajt végre. Ebben az esetben az adatok hozzáadása és törlése addig nem látható, amíg az információ frissül és a kurzor ki nem választja új verzió rögzíti, ha változások történtek rajtuk.

A statikus kurzorok leginkább információfeldolgozó rendszerekhez használhatók, pl. jelentési rendszerekre vagy statisztikai és elemzési célokra. A statikus kurzor jobb nagy mennyiségű adat lekérésére. Az objektumok (ülőhelyek, jegyek) elektronikus vásárlására vagy lefoglalására szolgáló rendszerekben szükség van a frissített információk dinamikus észlelésére a változások során. Ilyen esetekben dinamikus kurzort használunk. Ezekben az alkalmazásokban az átvitt adatok mennyisége jellemzően kicsi, és az egyes rekordok szintjén érhető el.

A szekvenciális kurzorok nem teszik lehetővé az adatok fordított irányú lekérését, csak a kurzor elejétől a végéig. A szekvenciális kurzor nem tárolja az összes adatsor halmazát. Amint kijelölés történik a kurzorban, azonnal kiolvasásra kerülnek az adatbázisból, amely lehetővé teszi a felhasználók által az INSERT, UPDATE, DELETE parancsok segítségével az adatbázisban végrehajtott összes módosítás dinamikus tükrözését. A kurzor a legfrissebb adatállapotot olvassa be.

Kurzor nyilatkozat

A kurzor_neve kurzor deklarálása a SELECT_utasításhoz ]]

Kulcsszó használatakor HELYI Létrejön egy helyi kurzor, amely csak a blokkon, triggeren, tárolt eljáráson vagy a felhasználó által definiált függvényen belül látható. Kulcsszó GLOBÁLIS, egy globális kurzort határoz meg, amely az aktuális kapcsolat bezárásáig létezik.

Operátor FORWARD_ONLY szekvenciális kurzort határoz meg, amely csak az első sortól az utolsóig terjedő irányban teszi lehetővé az adatok lekérését. A kezelő használatakor TEKERCS egy görgethető kurzor jön létre, amely lehetővé teszi az adatok tetszőleges sorrendben és irányból történő elérését.

A kurzor típusát az operátorok határozzák meg:

  • STATIC – statikus kurzor létrehozása;
  • DINAMIKUS - dinamikus kurzor létrehozása;
  • KEYSET - kulcskurzor létrehozása.

Ha a kurzort CSAK OLVASHATÓ argumentum megadása ELŐREPÖRGETÉS, akkor a létrehozott kurzor erre lesz optimalizálva gyors hozzáférés az adatokhoz. Ez az érv nem használható érvekkel együtt FORWARD_ONLYÉs OPTIMISTA.

Ha a kurzort az operátorral hozza létre OPTIMISTA, akkor tilos azokat a sorokat módosítani vagy törölni, amelyeket a kurzor megnyitása után módosítottak.

Egy argumentum megadásakor TYPE_WARNING a szerver implicit kurzortípus-módosítást fog jelenteni, ha az nem kompatibilis a SELECT lekérdezéssel.

Adatok lekérése kurzorról, lehívás

Közvetlenül a kurzor megnyitása után a következő paranccsal hozzáférhet a tartalmához:

A kezelő használatakor ELSŐ a kurzor eredményhalmazának első sora kerül visszaadásra, amely az aktuális sor lesz. Megadáskor UTOLSÓ a kurzor utolsó sora kerül visszaadásra. Ez lesz az aktuális sor is.

Operátor megadásakor KÖVETKEZŐ az eredményhalmazban közvetlenül az aktuális utáni sor kerül visszaadásra. Ez a sor lesz az aktuális sor. Alapértelmezett parancs FETCH pontosan ezt a módszert használja a sorok lekérésére.

Operátor megadásakor ELŐZETES az aktuális előtti sor kerül visszaadásra. Ez a sor lesz az aktuális sor.

Operátor ABSZOLÚT (sor_szám | @sor_szám_változó) egy sort ad vissza az abszolút sorszámával a kurzor teljes eredményhalmazában. A sorszám megadható konstans használatával vagy egy olyan változó neveként, amelyben a sorszámot tároljuk. A változónak egész adattípusnak kell lennie. Mind a pozitív, mind a negatív értékek fel vannak tüntetve. Pozitív érték megadásakor a sztringet a halmaz elejétől, míg a negatív értéket a végétől számítja a rendszer. A kiválasztott sor lesz az aktuális sor. Ha null értéket ad meg, akkor nem ad vissza sort.

Érv RELATÍV (sorok száma | @változó sorok száma) a soreltolást adja vissza a megadott számú sorral az aktuális után. Ha negatív sorszámot ad meg, akkor az a sor kerül visszaadásra, amely a megadott számú sor az aktuális előtt van. Null érték megadása az aktuális sort adja vissza. A visszaadott sor az aktuális sor lesz.

Globális kurzor megnyitásához meg kell adnia egy kulcsszót a neve előtt GLOBÁLIS. A kurzor neve változó használatával is megadható.

Kifejezésben INTO @változónév [,...n] a változók listája van meghatározva, amelyben a visszaadott sor megfelelő oszlopértékei tárolódnak. A változók sorrendjének meg kell egyeznie a kurzorban lévő oszlopok sorrendjével, a változó adattípusának pedig meg kell egyeznie a kurzoroszlop adattípusával.

Adatok módosítása és törlése kurzorral

Az adatok kurzorral történő módosításához ki kell adnia egy UPDATE parancsot a következő formátumban:

Egy műveletben az aktuális kurzorsor több oszlopának értéke módosítható, de mindegyiknek ugyanahhoz a táblázathoz kell tartoznia.

Az adatok kurzorral történő törléséhez használja a DELETE parancsot a következő formátumban:

Ennek eredményeként a kurzor aktuális sora törlődik.

Memória felszabadítása, felszabadítás

A kurzor memóriából való eltávolításához használja a parancsot

kurzor_neve lefoglalása;

@@FETCH_STATUS attribútum

A sorok kurzorban való jelenlétének meghatározásához globális változót kell használni @@FETCH_STATUS, amely nullától eltérő értéket vesz fel, ha nincs több sor a kurzorban. Ha a sorok halmaza még nem merült ki, akkor a @@FETCH_STATUS értéke nulla.

Példa egy kurzorra az SQL szerveren

@company varchar(50), @manager varchar(50), @message varchar(256) deklarálása; deklarálja a crs_clients kurzort lokálisnak a kiválasztott vállalathoz, menedzserhez az ügyfelek közül ahol city = "Moszkva" rendelés cég, menedzser szerint; nyomtatja ki az „Ügyfelek listáját”; crs_clients megnyitása; következő letöltése a crs_clients-ből a @cég, @menedzser; while @@FETCH_STATUS = 0 begin select @message = "Cég " + @company + " manager " + @manager; nyomtatás @üzenet; -- ugrás a következő rekordra. A következő rekord letöltése a crs_clientsből a @vállalat, @menedzser; vége; crs_clients bezárása; delocate crs_clients;

Megadjuk a kurzor definícióját. Típusainak és viselkedésének leírása található: statikus, dinamikus, szekvenciális és kulcskurzorok. Leírják a kurzorvezérlés alapelveit: kurzor létrehozása és megnyitása, adatok beolvasása, kurzor bezárása. Példák a kurzor programozására.

Kurzor koncepció

A relációs adatbázis lekérdezése általában több adatsort (rekordot) ad vissza, de az alkalmazás egyszerre csak egy rekordot dolgoz fel. Még ha egyszerre több sorral is foglalkozik (például táblázatok formájában jelenít meg adatokat), ezek száma korlátozott. Ezenkívül az adatok módosításakor, törlésekor vagy hozzáadásakor a munkaegység a sorozat. Ebben a helyzetben a kurzor fogalma kerül előtérbe, és ebben az összefüggésben a kurzor egy sorra mutató mutató.

A kurzor az SQL-ben az adatbázis-memória egy olyan területe, amely az utolsó SQL utasítás tárolására szolgál. Ha az aktuális utasítás egy adatbázis-lekérdezés, akkor a lekérdezési adatok egy sora, amelyet aktuális értéknek vagy aktuális kurzorsornak neveznek, szintén a memóriában tárolódik. A memória meghatározott területe el van nevezve, és az alkalmazásprogramok számára elérhető.

Jellemzően a kurzorokat arra használják, hogy kiválasszanak egy adatbázisból az abban tárolt információk egy részét. Egy adott időpontban egy kurzorsort ellenőrizhet az alkalmazás. A kurzorokat gyakran használják SQL utasítások, eljárási nyelveken írt alkalmazási programokba beépítve. Ezek egy részét az adatbázis-kiszolgáló implicit módon hozza létre, míg másokat a programozók határoznak meg.

Az SQL szabványnak megfelelően a kurzorokkal végzett munka során a következő fő műveletek különböztethetők meg:

  • teremtés ill kurzor deklaráció;
  • nyitó kurzor, azaz feltöltése többszintű memóriában tárolt adatokkal;
  • kiválasztás a kurzorbólés adatsorok módosítása vele;
  • a kurzor bezárása, ami után elérhetetlenné válik a felhasználói programok számára;
  • a kurzor felszabadítása, azaz a kurzor törlése objektumként, mert a bezárása nem feltétlenül szabadítja fel a hozzá tartozó memóriát.

A kurzor definíciója némileg változhat az egyes megvalósításokban. Például néha a fejlesztőnek kifejezetten fel kell szabadítania a kurzor számára lefoglalt memóriát. Után engedje el a kurzort hozzá tartozó memóriája is felszabadul. Ez lehetővé teszi a nevének újrafelhasználását. Más megvalósításokban mikor a kurzor bezárása a memória felszabadítása implicit módon történik. Közvetlenül a gyógyulás után elérhetővé válik más műveletekhez: újabb kurzor megnyitása stb.

Egyes esetekben a kurzor használata elkerülhetetlen. Ezt azonban lehetőség szerint kerülni kell, és szabványos adatfeldolgozási parancsokkal kell dolgozni: SELECT, UPDATE, INSERT, DELETE. Amellett, hogy a kurzorok nem teszik lehetővé a módosítási műveleteket a teljes adatmennyiségen, a kurzorral végzett adatfeldolgozási műveletek végrehajtásának sebessége észrevehetően alacsonyabb, mint a szabványos SQL-eszközöké.

Kurzorok megvalósítása MS SQL Server környezetben

Az SQL Server háromféle kurzort támogat:

  • Az SQL kurzorokat elsősorban triggerekben, tárolt eljárásokban és szkriptekben használják;
  • szerver kurzorok működnek a kiszolgálón, és megvalósítják az ODBC, OLE DB, DB_Library alkalmazásprogramozási felületét;
  • Az ügyfélkurzorok magán az ügyfélen vannak implementálva. Lekérik a teljes eredménysort a szerverről, és helyben tárolják, ami felgyorsítja az adatfeldolgozást, mivel csökkenti a hálózati műveletekre fordított időveszteséget.

A különböző típusú többfelhasználós alkalmazások különböző típusú párhuzamos adathozzáférést igényelnek. Egyes alkalmazások azonnali hozzáférést igényelnek az adatbázis változásaival kapcsolatos információkhoz. Ez jellemző a jegyfoglalási rendszerekre. Más esetekben, például a statisztikai jelentési rendszerekben, az adatok stabilitása azért fontos, mert ha folyamatosan módosítják, a programok nem lesznek képesek hatékonyan megjeleníteni az információkat. A különböző alkalmazásokhoz különböző kurzor-megvalósítások szükségesek.

Az SQL Serverben a kurzortípusok az általuk biztosított lehetőségektől függően változnak. A kurzor típusát a létrehozás szakaszában határozzák meg, és nem módosítható. Egyes kurzortípusok képesek észlelni a többi felhasználó által az eredménykészletben szereplő sorokon végrehajtott módosításokat. Az SQL Server azonban csak a sor elérése közben követi nyomon az ilyen sorok változásait, és nem teszi lehetővé a módosítások módosítását, ha a sor már beolvasásra került.

A kurzorok két kategóriába sorolhatók: egymás utániés görgethető. Egymást követő lehetővé teszi az adatok kiválasztását csak egy irányban - az elejétől a végéig. Görgethető kurzorok nagyobb cselekvési szabadságot biztosítanak - mindkét irányban lehet mozogni és a kurzor eredményhalmazának tetszőleges sorára ugrani Ha a program képes módosítani azokat az adatokat, amelyekre a kurzor mutat, akkor görgethetőnek és módosíthatónak nevezzük. Ha már a kurzorokról beszélünk, nem szabad megfeledkeznünk a tranzakciók elkülönítéséről. Amikor az egyik felhasználó módosít egy rekordot, egy másik a saját kurzorával olvassa be, sőt, módosíthatja ugyanazt a rekordot, ami szükségessé teszi az adatok integritásának megőrzését.

Az SQL Server támogatja a statikus, dinamikus, egymás utániés egy kulcskészlet vezérli.

A sémában statikus kurzor Az információkat egyszer beolvassa az adatbázisból, és pillanatfelvételként tárolja (valamilyen időpontban), így a másik felhasználó által az adatbázisban végrehajtott módosítások nem láthatók. Egy ideig a kurzor megnyitása a szerver a teljes eredménykészletében szereplő összes sort zárolja. Statikus kurzor létrehozása után nem változik, és mindig azt az adatsort jeleníti meg, amely a megnyitásakor létezett.

Ha más felhasználók megváltoztatják a kurzorban szereplő adatokat a forrástáblázatban, ez nem befolyásolja a statikus kurzor.

BAN BEN statikus kurzor Nem lehet módosítani, ezért mindig csak olvasható módban nyílik meg.

Dinamikus kurzor„élő” állapotban tartja az adatokat, de ehhez hálózati és szoftver erőforrások szükségesek. Használata dinamikus kurzorok a forrásadatok teljes másolata nem jön létre, hanem csak akkor történik dinamikus kiválasztás a forrástáblázatokból, amikor a felhasználó hozzáfér bizonyos adatokhoz. A lekérés során a szerver zárolja a sorokat, és a felhasználó által a kurzor teljes eredménykészletén végrehajtott változtatások láthatóak lesznek a kurzorban. Ha azonban egy másik felhasználó módosításokat végzett azután, hogy a kurzor lekérte az adatokat, azok nem fognak megjelenni a kurzorban.

A kurzort egy sor billentyű vezérli, e szélsőségek között középen helyezkedik el. A rekordokat a mintavételkor azonosítják, és így nyomon követik a változásokat. Ez a fajta kurzor hasznos a visszagörgetés megvalósítása során - ekkor a sorok hozzáadása és törlése nem látható az információ frissítéséig, és az illesztőprogram kiválasztja a rekord új verzióját, ha módosításokat hajt végre rajta.

Szekvenciális kurzorok nem engedik le az adatokat fordított irányban. A felhasználó csak a kurzor elejétől a végéig jelölhet ki sorokat. Soros kurzor nem tárolja az összes sor halmazát. A kurzorban való kijelölésük után azonnal beolvasásra kerülnek az adatbázisból, ami lehetővé teszi, hogy az INSERT, UPDATE, DELETE parancsokkal dinamikusan tükröződjön a felhasználók által az adatbázisban végzett változtatások. A kurzor az adatok legfrissebb állapotát mutatja.

Statikus kurzorok stabil nézetet biztosítanak az adatokról. Jók információs "raktározási" rendszerekhez: jelentési rendszerek alkalmazásához vagy statisztikai és elemzési célokra. Kívül, statikus kurzor másoknál jobban megbirkózik a nagy mennyiségű adat mintavételével. Ezzel szemben az elektronikus vásárlási vagy jegyfoglalási rendszerek megkövetelik a frissített információk dinamikus észlelését a változások során. Ilyen esetekben alkalmazzák dinamikus kurzor. Ezekben az alkalmazásokban az átvitt adatok mennyisége jellemzően kicsi, és a sor (egyedi rekord) szinten érhető el. A csoportos hozzáférés nagyon ritka.

Kurzorkezelés MS SQL Server környezetben

Kurzorvezérlés a következő parancsok végrehajtásával valósítható meg:

  • DECLARE - teremtés ill kurzor deklaráció;
  • NYISD KI - nyitó kurzor, azaz adatokkal való kitöltése;
  • FETCH kiválasztás a kurzorbólés adatsorok módosítása a kurzor segítségével;
  • BEZÁRÁS - a kurzor bezárása;
  • FELVONÁS – a kurzor felszabadítása, azaz a kurzor törlése objektumként.

Kurzor nyilatkozat

Az SQL szabvány a következő parancsot adja a kurzor létrehozásához:

Az INSENSITIVE kulcsszó használatával létrejön statikus kurzor. Adatváltozások nem engedélyezettek, továbbá a más felhasználók által végzett módosítások nem jelennek meg. Ha az INSENSITIVE kulcsszó hiányzik, a dinamikus kurzor.

Amikor megadja a SCROLL kulcsszót, a létrehozott kurzor bármilyen irányba görgethető, lehetővé téve bármilyen kiválasztási parancs használatát. Ha ezt az argumentumot kihagyjuk, a kurzor a következő lesz következetes, azaz megtekintése csak egy irányban lesz lehetséges – az elejétől a végéig.

A SELECT utasítás adja meg a SELECT kérés törzsét, amely meghatározza a kurzor eredményül kapott sorkészletét.

A FOR READ_ONLY megadása csak olvasható kurzort hoz létre, és nem teszi lehetővé az adatok módosítását. Eltér a statikustól, bár az utóbbi szintén nem teszi lehetővé az adatok megváltoztatását. Csak olvasható kurzorként deklarálható dinamikus kurzor, amely lehetővé teszi egy másik felhasználó által végzett módosítások megjelenítését.

A FOR UPDATE argumentumú kurzor létrehozása lehetővé teszi a kurzorban való végrehajtást adatváltozás vagy a megadott oszlopokban, vagy az OF oszlopnév argumentum hiányában az összes oszlopban.

Az MS SQL Server környezetben a kurzorlétrehozó parancs következő szintaxisa elfogadott:

<создание_курсора>::= DECLARE cursor_name CURSOR FOR SELECT_utasítás ]]

A LOCAL kulcsszó használatával helyi kurzor jön létre, amely csak az azt létrehozó csomag, trigger, tárolt eljárás vagy felhasználó által meghatározott függvény hatókörén belül látható. Amikor egy csomag, trigger, eljárás vagy függvény leáll, a kurzor implicit módon megsemmisül. Ha a kurzor tartalmát az azt létrehozó konstrukción kívül szeretné átadni, egy OUTPUT argumentumot kell hozzárendelnie a paraméteréhez.

Ha a GLOBAL kulcsszó van megadva, egy globális kurzor jön létre; az aktuális kapcsolat bezárásáig létezik.

A FORWARD_ONLY megadása létrehozza soros kurzor; Az adatokból csak az első sortól az utolsóig terjedő irányban lehet mintát venni.

A SCROLL megadása létrehozza görgethető kurzor; Az adatok bármilyen sorrendben és bármilyen irányban hozzáférhetők.

A STATIC megadása létrehozza statikus kurzor.

A KEYSET megadása kulcskurzort hoz létre.

A DYNAMIC megadásával létrejön dinamikus kurzor.

Ha megadja a FAST_FORWARD argumentumot egy READ_ONLY kurzorhoz, a létrehozott kurzor optimalizálva lesz a gyors adatelérésre. Ez az argumentum nem használható a FORWARD_ONLY vagy az OPTIMISTIC argumentumokkal együtt.

Az OPTIMISTIC argumentummal létrehozott kurzor megakadályozza az után módosított sorok módosítását vagy törlését. a kurzor megnyitása.

A TYPE_WARNING argumentum megadásával a szerver tájékoztatja a felhasználót a kurzortípus implicit változásáról, ha az nem kompatibilis a SELECT lekérdezéssel.

A kurzor megnyitása

Mert a kurzor megnyitásaés a kurzor létrehozásakor megadott SELECT lekérdezés adataival kitöltve használja a következő parancsot:

Után a kurzor megnyitása A hozzá tartozó SELECT utasítás végrehajtásra kerül, amelynek kimenete többszintű memóriában tárolódik.

Adatok lekérése a kurzorról

Közvetlenül utána a kurzor megnyitása a tartalmát (a megfelelő lekérdezés végrehajtásának eredményét) a következő paranccsal választhatja ki:

A FIRST megadása a kurzor teljes eredménykészletének legelső sorát adja vissza, amely az aktuális sor lesz.

A LAST megadása a kurzor legutóbbi sorát adja vissza. Ez lesz az aktuális sor is.

A NEXT megadása közvetlenül az aktuális sort adja vissza a teljes eredményhalmazban. Most aktuálissá válik. Alapértelmezés szerint a FETCH parancs ezt a módszert használja a sorok lekéréséhez.

A PRIOR kulcsszó az aktuális előtti sort adja vissza. Aktuálissá válik.

Érv ABSZOLÚT (sor_szám | @sor_szám_változó) egy sort ad vissza az abszolút sorszámával a kurzor teljes eredménykészletében. A sorszám megadható konstans használatával vagy egy olyan változó neveként, amelyben a sorszámot tároljuk. A változónak egész adattípusnak kell lennie. Mind a pozitív, mind a negatív értékek fel vannak tüntetve. Pozitív érték megadásakor a sztringet a halmaz elejétől, míg a negatív értéket a végétől számítja a rendszer. A kiválasztott sor az aktuális sor lesz. Ha null értéket ad meg, akkor nem ad vissza sort.

Érv RELATÍV (sorok száma | @változó sorok száma) azt a sort adja vissza, amely a megadott számú sor után van az aktuális után. Ha negatív sorszámot ad meg, akkor az a sor kerül visszaadásra, amely a megadott számú sor az aktuális előtt van. Null érték megadása az aktuális sort adja vissza. A visszaadott sor az aktuális sor lesz.

Nak nek globális kurzor megnyitása, meg kell adnia a GLOBAL kulcsszót a neve előtt. A kurzor neve változó használatával is megadható.

A tervezésben INTO @változónév [,...n] meg van adva egy változólista, amelyben a visszaadott sor megfelelő oszlopértékei kerülnek tárolásra. A változók megadásának sorrendjének meg kell egyeznie a kurzorban lévő oszlopok sorrendjével, a változó adattípusának pedig meg kell egyeznie a kurzoroszlop adattípusával. Ha az INTO konstrukció nincs megadva, akkor a FETCH parancs viselkedése hasonlít a SELECT parancs viselkedésére - az adatok megjelennek a képernyőn.

Adatok módosítása és törlése

A kurzor használatával történő módosításokhoz ki kell adnia egy UPDATE parancsot a következő formátumban:

Az aktuális kurzorsor több oszlopa módosítható egy műveletben, de mindegyiknek ugyanahhoz a táblához kell tartoznia.

Az adatok kurzorral történő törléséhez használja a DELETE parancsot a következő formátumban:

Ennek eredményeként a kurzorban beállított áramvonal törlődik.

A kurzor bezárása

A bezárás után a kurzor elérhetetlenné válik a program felhasználói számára. Zárt állapotban minden, a működése során felszerelt zár eltávolításra kerül. A lezárás csak nyitott kurzorokra alkalmazható. Zárva, de nem felszabadított kurzorújra megnyitható. A megnyitatlan kurzor bezárása nem megengedett.

Engedje el a kurzort

A kurzor bezárása nem feltétlenül szabadítja fel a hozzá tartozó memóriát. Egyes megvalósításoknak kifejezetten fel kell szabadítaniuk a DEALLOCATE utasítással. Után engedje el a kurzort A memória is felszabadul, lehetővé téve a kurzor nevének újrafelhasználását.

Annak ellenőrzésére, hogy a kurzor elérte-e a végét, ajánlott a @@FETCH_STATUS függvény használata

A @@FETCH_STATUS függvény a következőket adja vissza:

0, ha a letöltés sikeres volt;

1, ha a lehívás a kurzoron kívüli sor lekérésére tett kísérlet miatt sikertelen volt;

2, ha a lekérés egy törölt vagy módosított sor elérési kísérlete miatt sikertelen volt.

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 NYOMTATÁS "Bevásárlólista" NYILVÁNÍTÁSA klient_cursor KURSZOR HELYI KIVÁLASZTÁSHOZ Ügyfélkód, Vállalat, Vezetéknév FROM Ügyfél WHERE Város="Moszkva" ORDER BY Vállalat, Vezetéknév OPEN klient_cursor FETCH NEXT FROM klient_cursor INTO @id_kl, @firm, @fam CH_STATUS @FET =0 BEGIN SELECT @message="Ügyfél "+@fam+ "Cég "+ @firm PRINT @message" SELECT @message="Termék neve Vásárlás dátuma Költség" PRINT @üzenet KIJELENTÉSE tovar_cursor KURSZOR A KIVÁLASZTÁSHOZ Termék.Név, Tranzakció.Dátum, Termék .Ár* Tranzakció.Mennyiség, mint költség a terméktől BELSŐ CSATLAKOZÁS Tranzakció a termékre. Termékkód=Tranzakció.Termékkód WHERE Transaction.Customer Code=@id_kl OPEN tovar_cursor FETCH NEXT FROM FROM tovar_cursor INTO @nam, @d, @p IF @@FETCH_STATUS<>0 NYOMTATÁS "Nincs vásárlás" WHILE @@FETCH_STATUS=0 BEGIN SELECT @message=" "+@nam+" "+ CAST(@d AS CHAR(12))+" "+ CAST(@p AS CHAR(6)) NYOMTATÁS @message SET @s=@s+@p ELKÉRÉS KÖVETKEZŐ A tovar_cursortól BE @nam, @d, @p VÉGE CLOSE tovar_cursor FELVONÁSA tovar_cursor SELECT @message="Teljes költség "+ CAST(@s AS CHAR(6)) PRINT @message -- ugrás a következő kliensre -- HOZZÁ EL A KÖVETKEZŐ klient_cursor AZ @id_kl, @firm, @fam BEÁLLÍTÁSA VÉGE klient_cursor A klient_cursor LETÖLTÉSE 13.6. példa. Kurzor a moszkvai ügyfelek által vásárolt áruk listájának és teljes költségének megjelenítéséhez.

13.7. példa. Görgethető kurzor fejlesztése moszkvai ügyfelek számára. Ha a telefonszám 1-gyel kezdődik, törölje a klienst ezzel a számmal, és az első kurzorbejegyzésben cserélje ki a telefonszám első számjegyét 4-re.

BEJELENTKEZÉS @cég VARCHAR(50), @fam VARCHAR(50), @tel VARCHAR(8), @üzenet VARCHAR(80) "Ügyfelek listája" NYOMTATÁSA klient_cursor KURSZOR GLOBÁLIS GÖRGŐGOMB KIVÁLASZTÁSÁHOZ Cég, Vezetéknév, Telefon az ügyféltől WHERE Város ="Moszkva" RENDELÉS VÁLLALAT SZERINT, Vezetéknév FRISSÍTÉSHEZ MEGNYITÁS klient_cursor ELÉRÉS KÖVETKEZŐBŐL klient_cursor INTO @firm, @fam, @tel WHILE @@FETCH_STATUS=0 KEZDÉS KIVÁLASZT @message="Kliens "+@fam+ " Company "+ @firm " Telefon "+ @tel PRINT @üzenet -- ha a telefonszám 1-gyel kezdődik, -- törölje a klienst ezzel a számmal IF @tel LIKE '1%' TÖRLÉS Client WHERE CURRENT OF klient_cursor ELSE -- ugrás a következőre kliens FETCH NEXT FROM klient_cursor BE @firm, @fam, @tel VÉGE FETCH ABSOLUTE 1 FROM klient_cursor INTO @firm, @fam, @tel -- az első bejegyzésben cserélje ki a telefonszám első számjegyét 4 UPDATE Client SET Phone-ra ='4' + JOBB(@ tel,LEN(@tel)-1)) WHERE CURRENT OF klient_cursor SELECT @message="Kliens "+@fam+" Cég "+ @firm "Telefon "+ @tel NYOMTATÁS @üzenet CLOSE klient_cursor DEALLOCATE klient_cursor 13.7. példa. Görgethető kurzor moszkvai ügyfelek számára.

13.8. példa. Használat kurzort az eljárás kimeneti paramétereként. Az eljárás egy adatkészletet – a termékek listáját – ad vissza.

Az eljárás meghívása és az adatok kinyomtatása a kimeneti kurzorból a következőképpen történik:

DECLARE @my_cur CURSOR DECLARE @n VARCHAR(20) EXEC my_proc @cur=@my_cur OUTPUT FETCH NEXT FROM @my_cur INTO @n SELECT @n WHILE (@@FETCH_STATUS=0) INDÍTSA KÖVETKEZŐ LEHETSÉGET @my_cur @n @n VÉGE BEZÁR @my_cur FELTÉTELEZÉS @my_cur




Top