Megosztás a következőn keresztül:


KURZOR DEKLARÁLÁSA (Transact-SQL)

A következőkre vonatkozik:SQL ServerAzure SQL DatabaseFelügyelt Azure SQL-példánySQL-adatbázis a Microsoft Fabricben

Meghatározza a Transact-SQL kiszolgálói kurzor attribútumait, például a görgetési viselkedését és a kurzort működtető eredménykészlet létrehozásához használt lekérdezést. DECLARE CURSOR Az ISO-szabványon alapuló szintaxist és egy szintaxist is elfogad Transact-SQL bővítmények halmazával.

Transact-SQL szintaxis konvenciók

Syntax

ISO szintaxis:

DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
    FOR select_statement
    [ FOR { READ_ONLY | UPDATE [ OF column_name [ , ...n ] ] } ]
[ ; ]

Transact-SQL bővített szintaxis:

DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
    [ FORWARD_ONLY | SCROLL ]
    [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
    [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
    [ TYPE_WARNING ]
    FOR select_statement
    [ FOR UPDATE [ OF column_name [ , ...n ] ] ]
[ ; ]

Arguments

cursor_name

A definiált Transact-SQL kiszolgálói kurzor neve. cursor_name meg kell felelniük az azonosítókra vonatkozó szabályoknak.

ÉRZÉKETLEN

Definiál egy kurzort, amely ideiglenes másolatot készít a kurzor által használandó adatokról. A kurzorhoz érkező összes kérésre a rendszer a következő ideiglenes táblázatból tempdbválaszol: . Ezért az alaptábla módosításai nem jelennek meg a kurzorhoz beolvasott beolvasások által visszaadott adatokban, és ez a kurzor nem teszi lehetővé a módosításokat. Ha az ISO-szintaxist használja, ha INSENSITIVE nincs megadva, a véglegesített törlések és a mögöttes táblákon (bármely felhasználó által) végrehajtott frissítések megjelennek a későbbi lekérésekben.

KÉZIRATTEKERCS

Megadja, hogy az összes beolvasási beállítás (FIRST, LAST, , PRIORNEXT, RELATIVE, ) ABSOLUTEelérhető-e. Ha SCROLL nincs megadva ISO-ban DECLARE CURSOR, NEXT az egyetlen támogatott beolvasási lehetőség. SCROLL nem adhatók meg, ha FAST_FORWARD szintén meg van adva. Ha SCROLL nincs megadva, akkor csak a beolvasási beállítás NEXT érhető el, és a kurzor lesz FORWARD_ONLY.

select_statement

A kurzor eredményhalmazát meghatározó standard SELECT utasítás. A kulcsszavak FOR BROWSE, és INTO nem engedélyezettek a kurzordeklaráció select_statement .

Az SQL Server implicit módon átalakítja a kurzort egy másik típussá, ha select_statement záradékok ütköznek a kért kurzortípus funkciójával.

READ_ONLY

Megakadályozza a kurzoron keresztül végrehajtott frissítéseket. A kurzorra nem lehet hivatkozni egy WHERE CURRENT OF záradékban vagy UPDATE utasításbanDELETE. Ez a beállítás felülírja a frissíteni kívánt kurzor alapértelmezett képességét.

UPDATE [ OF column_name [ ,... n ] ]

A kurzoron belüli frissíthető oszlopokat definiálja. Ha OF <column_name> [, <... n> ] meg van adva, csak a felsorolt oszlopok engedélyezik a módosításokat. Ha UPDATE oszloplista nélkül van megadva, az összes oszlop frissíthető.

cursor_name

A definiált Transact-SQL kiszolgálói kurzor neve. cursor_name meg kell felelniük az azonosítókra vonatkozó szabályoknak.

LOCAL

Megadja, hogy a kurzor hatóköre helyi legyen a köteghez, a tárolt eljáráshoz vagy az eseményindítóhoz, amelyben a kurzor létrejött. A kurzornév csak ebben a hatókörben érvényes. A kurzorra hivatkozhatnak a köteg helyi kurzorváltozói, a tárolt eljárás vagy az eseményindító, vagy egy tárolt eljárásparaméter OUTPUT . A OUTPUT rendszer egy paraméterrel adja vissza a helyi kurzort a hívó kötegnek, a tárolt eljárásnak vagy az eseményindítónak, amely hozzárendelheti a paramétert egy kurzorváltozóhoz, hogy a tárolt eljárás leállása után hivatkozzon a kurzorra. A kurzor implicit módon felszabadítva lesz a köteg, a tárolt eljárás vagy az eseményindító leállásakor, kivéve, ha a kurzort OUTPUT egy paraméterben adták vissza. Ha egy paraméterben OUTPUT visszalép, a kurzor felszabadítva lesz, amikor az utolsó, rá hivatkozó változó felszabadítva van, vagy kimegy a hatókörből.

GLOBAL

Megadja, hogy a kurzor hatóköre globális legyen a kapcsolathoz. A kurzor nevére bármely tárolt eljárásban vagy kötegben hivatkozhat, amelyet a kapcsolat hajt végre. A kurzor csak implicit módon van felszabadítva a leválasztáskor.

Note

Ha egyik sem GLOBAL , vagy LOCAL nincs megadva, az alapértelmezett beállítás a helyi kurzoradatbázis alapértelmezett beállításával van szabályozva.

FORWARD_ONLY

Azt adja meg, hogy a kurzor csak előre tud lépni, és az elsőtől az utolsó sorig görgethető. FETCH NEXT az egyetlen támogatott beolvasási lehetőség. Az aktuális felhasználó (vagy más felhasználók által véglegesített) összes olyan beszúrási, frissítési és törlési utasítása, amely hatással van az eredményhalmaz soraira, a sorok lekérésekor látható. Mivel a kurzor nem görgethető visszafelé, az adatbázis soraiban a sor beolvasása után végrehajtott módosítások nem láthatók a kurzoron keresztül. A csak előre mutató kurzorok alapértelmezés szerint dinamikusak, ami azt jelenti, hogy a rendszer az aktuális sor feldolgozásakor minden módosítást észlel. Ez gyorsabb kurzormegnyitást tesz lehetővé, és lehetővé teszi, hogy az eredményhalmaz megjelenítse az alapul szolgáló táblákon végrehajtott frissítéseket. Bár a csak előre mutató kurzorok nem támogatják a visszamenőleges görgetést, az alkalmazások a kurzor bezárásával és újbóli megnyitásával visszatérhetnek az eredményhalmaz elejére.

Ha FORWARD_ONLY a kurzor a STATIC, KEYSETvagy DYNAMIC kulcsszavak nélkül van megadva, a kurzor dinamikus kurzorként működik. FORWARD_ONLY Ha SCROLL nincs megadva, FORWARD_ONLY akkor az alapértelmezett érték, kivéve, ha a kulcsszavak STATICmeg KEYSETDYNAMIC vannak adva. STATIC, KEYSETés DYNAMIC a kurzorok alapértelmezés szerint a .SCROLL Ellentétben az adatbázis API-ival, például az ODBC-vel és az ADO-valFORWARD_ONLY, STATIC az , KEYSETés DYNAMIC Transact-SQL kurzorok is támogatottak.

STATIC

Azt adja meg, hogy a kurzor mindig az eredményhalmazt jeleníti meg a kurzor első megnyitásakor, és ideiglenes másolatot készít a kurzor által használandó adatokról. A kurzorhoz érkező összes kérésre a rendszer a következő ideiglenes táblázatból tempdbválaszol: . Ezért az alaptáblákon végrehajtott beszúrások, frissítések és törlések nem jelennek meg a kurzorhoz beolvasott beolvasások által visszaadott adatokban, és ez a kurzor nem észleli a kurzor megnyitása után az eredményhalmaz tagságán, sorrendjén vagy értékein végrehajtott módosításokat. A statikus kurzorok észlelhetik a saját frissítéseiket, törléseiket és beszúrásaikat, bár erre nincs szükség.

Tegyük fel például, hogy egy statikus kurzor lekéri a sort, egy másik alkalmazás pedig frissíti a sort. Ha az alkalmazás újrafeszüli a sort a statikus kurzortól, a látott értékek változatlanok maradnak a másik alkalmazás módosításai ellenére. A görgetés minden típusa támogatott.

KEYSET

Megadja, hogy a kurzorban lévő sorok tagsága és sorrendje rögzített legyen a kurzor megnyitásakor. A sorokat egyedileg azonosító kulcskészlet a tempdb néven ismert táblába van beépítve. Ez a kurzor funkcióval rendelkezik a statikus és a dinamikus kurzor között, így képes észlelni a változásokat. A statikus kurzorhoz hasonlóan nem mindig észleli az eredményhalmaz tagságának és sorrendjének változásait. A dinamikus kurzorhoz hasonlóan az eredményhalmaz sorainak értékeinek változásait is észleli.

A billentyűkészlet-vezérelt kurzorokat egyedi azonosítók (kulcsok) készlete vezérli, amelyeket kulcskészletnek neveznek. A kulcsok olyan oszlopkészletből épülnek fel, amely egyedileg azonosítja az eredményhalmaz sorait. A kulcskészlet a lekérdezési utasítás által visszaadott összes sor kulcsértékeinek halmaza. A kulcskészlet-vezérelt kurzorok esetében a rendszer létrehoz és ment egy kulcsot a kurzor minden egyes sorához, és az ügyfél-munkaállomáson vagy a kiszolgálón tárolja. Az egyes sorok elérésekor a tárolt kulcs használatával lekérheti az aktuális adatértékeket az adatforrásból. A kulcskészlet-vezérelt kurzorban az eredményhalmaz tagsága le van fagyasztva, amikor a kulcskészlet teljesen fel van töltve. Ezt követően a tagságot érintő hozzáadások vagy frissítések nem részei az eredményhalmaznak, amíg újra meg nem nyitják.

Az adatértékek (a kulcskészlet tulajdonosa vagy más folyamatok által végzett) módosítása látható, amikor a felhasználó végiggörget az eredményhalmazon:

  • Ha törölnek egy sort, a sor beolvasásának kísérlete @@FETCH_STATUS a következőt adja vissza-2, mert a törölt sor résként jelenik meg az eredményhalmazban. A sor kulcsa létezik a kulcskészletben, de a sor már nem létezik az eredményhalmazban.

  • A kurzoron kívül (más folyamatok által) készített beszúrások csak akkor láthatók, ha a kurzort bezárták és újra megnyitották. A kurzoron belülről készített beszúrások az eredményhalmaz végén láthatók.

  • A kurzoron kívüli kulcsértékek frissítése hasonlít a régi sor törlésére, amelyet az új sor beszúrása követ. Az új értékeket tartalmazó sor nem látható, és a régi értékekkel @@FETCH_STATUS-2kísérli meg beolvasni a sort. Az új értékek akkor láthatók, ha a módosítás a kurzoron keresztül történik a WHERE CURRENT OF záradék megadásával.

Note

Ha a lekérdezés legalább egy táblára egyedi index nélkül hivatkozik, a billentyűkészlet-kurzor statikus kurzorrá alakul.

DYNAMIC

Olyan kurzort definiál, amely tükrözi az eredményhalmaz soraiban végrehajtott összes adatmódosítást, miközben görget a kurzor körül, és beolvassa az új rekordot, függetlenül attól, hogy a módosítások a kurzoron belülről vagy a kurzoron kívüli más felhasználóktól történnek. Ezért az összes felhasználó által tett beszúrási, frissítési és törlési utasítások a kurzoron keresztül láthatók. A sorok adatértékei, sorrendje és tagsága minden beolvasáskor változhat. A ABSOLUTE beolvasási beállítás nem támogatott dinamikus kurzorokkal. A kurzoron kívül végrehajtott frissítések csak véglegesítésük után láthatók (kivéve, ha a kurzor tranzakcióelkülönítési szintje be van állítva UNCOMMITTED).

Tegyük fel például, hogy egy dinamikus kurzor két sort kér le, egy másik alkalmazás pedig frissíti az egyik sort, és törli a másikat. Ha a dinamikus kurzor lekéri ezeket a sorokat, nem találja a törölt sort, hanem megjeleníti a frissített sor új értékeit.

FAST_FORWARD

Egy , kurzort FORWARD_ONLYad meg, READ_ONLY amelyen engedélyezve van a teljesítményoptimalizálás. FAST_FORWARD nem adható meg, ha SCROLL vagy FOR_UPDATE meg is van adva. Ez a kurzortípus nem teszi lehetővé az adatmódosításokat a kurzoron belülről.

Note

Mindkettőt FAST_FORWARD , és FORWARD_ONLY ugyanabban DECLARE CURSOR az utasításban is használható.

READ_ONLY

Megakadályozza a kurzoron keresztül végrehajtott frissítéseket. A kurzorra nem lehet hivatkozni egy WHERE CURRENT OF záradékban vagy UPDATE utasításbanDELETE. Ez a beállítás felülírja a frissíteni kívánt kurzor alapértelmezett képességét.

SCROLL_LOCKS

Megadja, hogy a kurzoron keresztül végrehajtott helyhez kötött frissítések vagy törlések garantáltan sikeresek legyenek. Az SQL Server zárolja a sorokat, miközben beolvassa őket a kurzorba, így biztosítva azok későbbi módosításokhoz való rendelkezésre állását. SCROLL_LOCKS nem adható meg, ha FAST_FORWARD vagy STATIC meg is van adva.

OPTIMISTA

Azt adja meg, hogy a kurzoron keresztül végrehajtott helyhez kötött frissítések vagy törlések nem sikeresek-e, ha a sor frissült, mivel beolvasták a kurzorba. Az SQL Server nem zárolja a sorokat, mivel beolvassa őket a kurzorba. Ehelyett az időbélyeg oszlopértékeinek összehasonlítását használja, vagy egy ellenőrzőösszeg-értéket, ha a táblázat nem tartalmaz időbélyegoszlopot , annak megállapításához, hogy a sor módosult-e, miután beolvasták a kurzorba.

Ha a sor módosult, a megkísérelt frissítés vagy törlés meghiúsul. OPTIMISTIC nem adhatók meg, ha FAST_FORWARD szintén meg van adva.

Ha STATIC a OPTIMISTIC kurzor argumentummal együtt van megadva, a kettő kombinációja implicit módon a használat STATIC és READ_ONLY az argumentumok, illetve az STATICFORWARD_ONLY argumentumok kombinációjának megfelelővé lesz konvertálva.

TYPE_WARNING

Azt adja meg, hogy a rendszer figyelmeztető üzenetet küld az ügyfélnek, amikor a kurzor implicit módon konvertálódik a kért típusról egy másikra.

A rendszer nem küld figyelmeztetést az ügyfélnek a kurzor argumentumainak és kombinációinak OPTIMISTIC használatakor, és a kurzor implicit módon egy vagy STATIC több kurzor megfelelője STATIC READ_ONLY lesz.STATIC FORWARD_ONLY Az átalakítás az READ_ONLYFAST_FORWARD ügyfelek szemszögéből vált és READ_ONLY kurzort eredményez.

select_statement

A kurzor eredményhalmazát meghatározó standard SELECT utasítás. A kulcsszavakCOMPUTE, COMPUTE BYés FOR BROWSEINTO nem engedélyezettek a kurzordeklaráció select_statement.

Note

A kurzordeklaráción belül lekérdezési tippet is használhat. Ha azonban a záradékot is használja, adja meg FOR UPDATE OF a OPTION (<query_hint>) következőtFOR UPDATE OF: .

Az SQL Server implicit módon átalakítja a kurzort egy másik típussá, ha select_statement záradékok ütköznek a kért kurzortípus funkciójával.

COLUMN_NAME FRISSÍTÉSE [ ,... n ] ]

A kurzoron belüli frissíthető oszlopokat definiálja. Ha OF <column_name> [, <... n>] meg van adva, csak a felsorolt oszlopok engedélyezik a módosításokat. Ha UPDATE oszloplista nélkül van megadva, az összes oszlop frissíthető, kivéve, ha az READ_ONLY egyidejűség beállítás meg van adva.

Remarks

DECLARE CURSOR Meghatározza a Transact-SQL kiszolgálói kurzor attribútumait, például a görgetési viselkedését és a kurzort működtető eredménykészlet létrehozásához használt lekérdezést. Az OPEN utasítás feltölti az eredményhalmazt, és FETCH visszaad egy sort az eredményhalmazból. Az CLOSE utasítás felszabadítja a kurzorhoz társított aktuális eredményhalmazt. Az DEALLOCATE utasítás felszabadítja a kurzor által használt erőforrásokat.

Az utasítás első formája az DECLARE CURSOR ISO-szintaxist használja a kurzor viselkedésének deklarálására. A második felhasználási forma DECLARE CURSOR Transact-SQL bővítmények, amelyek lehetővé teszik a kurzorok definiálását ugyanazokkal a kurzortípusokkal, amelyeket az ODBC vagy az ADO adatbázis API kurzorfüggvényeiben használnak.

Nem keverheti össze a két űrlapot. Ha a kulcsszó előtt adja meg a SCROLLINSENSITIVECURSOR kulcsszavakat, nem használhat kulcsszavakat a kulcsszavak és CURSOR a FOR <select_statement> kulcsszavak között. Ha kulcsszavakat ad meg a kulcsszavak és a CURSOR kulcsszavak között, akkor nem adhatja meg vagy FOR <select_statement> nem előzheti SCROLL meg a kulcsszótINSENSITIVE.CURSOR

Ha egy DECLARE CURSOR Transact-SQL szintaxis nem adja meg READ_ONLY, OPTIMISTICvagy SCROLL_LOCKSaz alapértelmezett érték a következő:

  • Ha az utasítás nem támogatja a SELECT frissítéseket (nem megfelelő engedélyek, olyan távoli táblák elérése, amelyek nem támogatják a frissítéseket stb.), a kurzor a READ_ONLYkövetkező: .

  • STATICés FAST_FORWARD a kurzorok alapértelmezés szerint a .READ_ONLY

  • DYNAMICés KEYSET a kurzorok alapértelmezés szerint a .OPTIMISTIC

A kurzornevekre csak más Transact-SQL utasítások hivatkozhatnak. Az adatbázis API-függvényei nem hivatkozhatnak rájuk. A kurzor deklarálása után például a kurzor neve nem hivatkozható az OLE DB, ODBC vagy ADO függvényekből vagy metódusokból. A kurzorsorokat nem lehet lekérni az API-k beolvasási függvényeivel vagy metódusaival; a sorokat csak Transact-SQL FETCH utasításokkal lehet beolvasni.

A kurzor deklarálása után ezek a rendszer által tárolt eljárások használhatók a kurzor jellemzőinek meghatározására.

Rendszer által tárolt eljárások Description
sp_cursor_list A kapcsolaton jelenleg látható kurzorok és attribútumaik listáját adja vissza.
sp_describe_cursor A kurzor attribútumait ismerteti, például azt, hogy csak előre vagy görgethető kurzorról van-e szó.
sp_describe_cursor_columns A kurzor eredményhalmazában lévő oszlopok attribútumait ismerteti.
sp_describe_cursor_tables A kurzor által elért alaptáblákat ismerteti.

A változók a kurzort deklaráló select_statement részeként használhatók. A kurzorváltozó értékei nem változnak a kurzor deklarálása után.

Permissions

DECLARE CURSOR A kurzorban használt nézetekre, táblákra és oszlopokra vonatkozó engedélyekkel rendelkező SELECT felhasználók alapértelmezett engedélyei.

Limitations

Fürtözött oszlopcentrikus indexet tartalmazó táblán nem használhat kurzort vagy eseményindítót. Ez a korlátozás nem vonatkozik a nemclustered oszlopcentrikus indexekre. A kurzorokat és az eseményindítókat nemclustered oszlopcentrikus indexet tartalmazó táblán használhatja.

Examples

A. Alapszintű kurzor és szintaxis használata

A kurzor megnyitásakor létrehozott eredményhalmaz a tábla összes sorát és oszlopát tartalmazza. Ez a kurzor frissíthető, és az összes frissítés és törlés a kurzorra irányuló beolvasásokban jelenik meg. FETCH NEXT az egyetlen elérhető lekérés, mert a SCROLL beállítás 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éskimenet létrehozásához

Az alábbi példa bemutatja, hogyan ágyazhatók be a kurzorok összetett jelentések létrehozásához. A belső kurzor minden szállítóhoz deklarálva van.

SET NOCOUNT ON;

DECLARE @vendor_id INT, @vendor_name NVARCHAR(50),
    @message VARCHAR(80), @product NVARCHAR(50);

PRINT '-------- Vendor Products Report --------';

DECLARE vendor_cursor CURSOR FOR
SELECT VendorID, Name
FROM Purchasing.Vendor
WHERE PreferredVendorStatus = 1
ORDER BY VendorID;

OPEN vendor_cursor

FETCH NEXT FROM vendor_cursor
INTO @vendor_id, @vendor_name

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT ' '
    SELECT @message = '----- Products From Vendor: ' +
        @vendor_name

    PRINT @message

    -- Declare an inner cursor based
    -- on vendor_id from the outer cursor.

    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  -- Variable value from the outer cursor

    OPEN product_cursor
    FETCH NEXT FROM product_cursor INTO @product

    IF @@FETCH_STATUS <> 0
        PRINT '         <<None>>'

    WHILE @@FETCH_STATUS = 0
    BEGIN

        SELECT @message = '         ' + @product
        PRINT @message
        FETCH NEXT FROM product_cursor INTO @product
        END

    CLOSE product_cursor
    DEALLOCATE product_cursor
        -- Get the next vendor.
    FETCH NEXT FROM vendor_cursor
    INTO @vendor_id, @vendor_name
END
CLOSE vendor_cursor;
DEALLOCATE vendor_cursor;