Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Platí pro:SQL Server
Azure SQL Database
Azure SQL spravovaná instance
Azure SQL databáze v Microsoft Fabric Preview
Definuje atributy kurzoru serveru Transact-SQL, například jeho chování posouvání a dotaz použitý k sestavení sady výsledků, na které kurzor pracuje.
DECLARE CURSOR přijímá syntaxi založenou na standardu ISO i syntaxi pomocí sady rozšíření Transact-SQL.
Syntax
ISO syntax:
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ_ONLY | UPDATE [ OF column_name [ , ...n ] ] } ]
[ ; ]
Transact-SQL rozšířená syntaxe:
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
Název kurzoru serveru Transact-SQL definovaný. cursor_name musí odpovídat pravidlům identifikátorů.
INSENSITIVE
Definuje kurzor, který vytvoří dočasnou kopii dat, která se použijí kurzorem. Všechny požadavky na kurzor jsou zodpovězeny z této dočasné tabulky v tempdb. Úpravy základní tabulky se proto neprojeví v datech vrácených načtením tohoto kurzoru a tento kurzor neumožňuje úpravy. Pokud se použije syntaxe ISO, pokud INSENSITIVE je vynechána, potvrzené odstranění a aktualizace provedené v podkladových tabulkách (libovolným uživatelem) se projeví v následných načteních.
SCROLL
Určuje, že jsou k dispozici všechny možnosti načítání (FIRST, LAST, NEXTPRIOR, RELATIVE, , ABSOLUTE). Pokud SCROLL není zadán v iso , NEXT je jedinou podporovanou DECLARE CURSORmožností načtení.
SCROLL nelze zadat, pokud FAST_FORWARD je zadán také. Pokud SCROLL není zadán, je k dispozici pouze možnost NEXT načtení a kurzor se stane FORWARD_ONLY.
select_statement
Standardní SELECT příkaz, který definuje sadu výsledků kurzoru. Klíčová slova FOR BROWSEa INTO nejsou povolena v rámci select_statement deklarace kurzoru.
SQL Server implicitně převede kurzor na jiný typ, pokud klauzule v select_statement konfliktu s funkcemi požadovaného typu kurzoru.
READ_ONLY
Zabrání aktualizacím provedeným tímto kurzorem. Kurzor nelze odkazovat v WHERE CURRENT OF klauzuli v klauzuli nebo UPDATEDELETE příkazu. Tato možnost přepíše výchozí funkci kurzoru, která se má aktualizovat.
UPDATE [ OF column_name [ ,... n ] ]
Definuje aktualizovatelné sloupce v kurzoru. Pokud OF <column_name> [, <... n> ] je zadáno, povolují úpravy pouze sloupce uvedené v seznamu. Pokud UPDATE je zadán bez seznamu sloupců, je možné aktualizovat všechny sloupce.
cursor_name
Název kurzoru serveru Transact-SQL definovaný. cursor_name musí odpovídat pravidlům identifikátorů.
LOCAL
Určuje, že rozsah kurzoru je místní pro dávku, uloženou proceduru nebo aktivační událost, ve které byl kurzor vytvořen. Název kurzoru je platný pouze v rámci tohoto oboru. Na kurzor lze odkazovat pomocí místních proměnných kurzoru v dávce, uložené proceduře nebo triggeru nebo parametru uložené procedury OUTPUT . Parametr OUTPUT se používá k předání místního kurzoru zpět volající dávce, uložené procedury nebo triggeru, který může přiřadit parametr proměnné kurzoru odkaz na kurzor po ukončení uložené procedury. Kurzor je implicitně uvolněn při ukončení dávky, uložené procedury nebo triggeru, pokud kurzor nebyl předán zpět v parametru OUTPUT . Pokud předá parametr zpět OUTPUT , kurzor se uvolní, když se poslední proměnná odkazující na tento parametr uvolní nebo přestane být oborem.
GLOBAL
Určuje, že rozsah kurzoru je globální pro připojení. Na název kurzoru se dá odkazovat v libovolné uložené proceduře nebo dávce spuštěné připojením. Kurzor je při odpojení implicitně uvolněný.
Note
Pokud ani GLOBAL jedno nebo LOCAL není zadáno, výchozí nastavení je řízeno nastavením výchozí možnosti místní databáze kurzoru .
FORWARD_ONLY
Určuje, že kurzor se může pohybovat pouze dopředu a posunovat se od prvního k poslednímu řádku.
FETCH NEXT je jedinou podporovanou možností načítání. Všechny příkazy vložení, aktualizace a odstranění provedené aktuálním uživatelem (nebo potvrzené jinými uživateli), které ovlivňují řádky v sadě výsledků, jsou viditelné při načítání řádků. Vzhledem k tomu, že se kurzor nedá posunout dozadu, změny řádků v databázi po načtení řádku se přes kurzor nezobrazují. Kurzory pouze vpřed jsou ve výchozím nastavení dynamické, což znamená, že se při zpracování aktuálního řádku zjistí všechny změny. To poskytuje rychlejší otevření kurzoru a umožňuje sadě výsledků zobrazit aktualizace provedené v podkladových tabulkách. Zatímco kurzory pouze vpřed nepodporují zpětné posouvání, aplikace se můžou vrátit na začátek sady výsledků zavřením a opětovným otevřením kurzoru.
Pokud FORWARD_ONLY je zadána bez STATIC, KEYSETnebo DYNAMIC klíčových slov, kurzor funguje jako dynamický kurzor. Pokud FORWARD_ONLY není zadána nebo SCROLL není zadána, je výchozí, FORWARD_ONLY pokud nejsou zadána STATICklíčová slova , KEYSETnebo DYNAMIC nejsou zadány.
STATIC, KEYSETa DYNAMIC kurzory jsou ve výchozím nastavení .SCROLL Na rozdíl od databázových rozhraní API, jako jsou ROZHRANÍ ODBC a ADO, FORWARD_ONLY se podporuje s STATICKEYSETkurzory a DYNAMIC Transact-SQL.
STATIC
Určuje, že kurzor vždy zobrazí sadu výsledků tak, jak byla při prvním otevření kurzoru, a vytvoří dočasnou kopii dat, která bude použit kurzorem. Všechny požadavky na kurzor jsou zodpovězeny z této dočasné tabulky v tempdb. Vložení, aktualizace a odstranění provedené v základních tabulkách se proto neprojeví v datech vrácených načtením tohoto kurzoru a tento kurzor nezjistí změny provedené ve členství, pořadí nebo hodnotách sady výsledků po otevření kurzoru. Statické kurzory můžou rozpoznat vlastní aktualizace, odstranění a vložení, i když k tomu nejsou potřeba.
Předpokládejme například, že statický kurzor načte řádek a jiná aplikace pak tento řádek aktualizuje. Pokud aplikace znovu načte řádek ze statického kurzoru, hodnoty, které uvidí, se bez ohledu na změny provedené druhou aplikací nezmění. Podporují se všechny typy posouvání.
KEYSET
Určuje, že členství a pořadí řádků v kurzoru jsou při otevření kurzoru pevné. Sada klíčů, které jednoznačně identifikují řádky, je integrovaná do tabulky tempdb označované jako sada klíčů. Tento kurzor poskytuje funkce mezi statickým a dynamickým kurzorem ve své schopnosti detekovat změny. Stejně jako statický kurzor ne vždy rozpoznává změny členství a pořadí sady výsledků. Podobně jako dynamický kurzor rozpozná změny hodnot řádků v sadě výsledků.
Kurzory řízené sadou klíčů jsou řízeny sadou jedinečných identifikátorů (klíčů) označovaných jako sada klíčů. Klíče jsou vytvořeny ze sady sloupců, které jednoznačně identifikují řádky v sadě výsledků. Sada klíčů je sada hodnot klíče ze všech řádků vrácených příkazem dotazu. Pomocí kurzorů řízených klávesovými sadami se klíč sestaví a uloží pro každý řádek v kurzoru a uloží se buď na klientské pracovní stanici, nebo na serveru. Při přístupu k jednotlivým řádkům se uložený klíč použije k načtení aktuálních hodnot dat ze zdroje dat. V kurzoru řízeném pomocí sady klíčů se členství v sadě výsledků zablokuje, když je sada klíčů plně naplněná. Potom přidání nebo aktualizace, které mají vliv na členství, nejsou součástí sady výsledků, dokud se znovu neotevře.
Změny hodnot dat (provedené vlastníkem sady klíčů nebo jinými procesy) jsou viditelné, když uživatel prochází sadou výsledků:
Pokud je řádek odstraněný, pokus o načtení řádku vrátí
@@FETCH_STATUS,-2protože odstraněný řádek se zobrazí jako mezera v sadě výsledků. Klíč pro řádek existuje v sadě klíčů, ale řádek již v sadě výsledků neexistuje.Vložení provedená mimo kurzor (jinými procesy) jsou viditelná pouze v případě, že je kurzor zavřený a znovu otevřen. Vložení provedená z kurzoru jsou viditelná na konci sady výsledků.
Aktualizace hodnot klíčů mimo kurzor se podobají odstranění starého řádku následovaného vložením nového řádku. Řádek s novými hodnotami není viditelný a pokusí se načíst řádek se starými hodnotami, které vrátí hodnotu
@@FETCH_STATUS-2. Nové hodnoty jsou viditelné, pokud je aktualizace provedena kurzorem zadánímWHERE CURRENT OFklauzule.
Note
Pokud dotaz odkazuje alespoň na jednu tabulku bez jedinečného indexu, kurzor sady klíčů se převede na statický kurzor.
DYNAMIC
Definuje kurzor, který odráží všechny změny dat provedené v řádcích v sadě výsledků, když se posunete kolem kurzoru a načtete nový záznam bez ohledu na to, jestli se změny vyskytují uvnitř kurzoru nebo jinými uživateli mimo kurzor. Proto jsou všechny příkazy insert, update a delete provedené všemi uživateli viditelné přes kurzor. Hodnoty dat, pořadí a členství v řádcích se můžou při každém načtení měnit. Možnost ABSOLUTE načtení není podporována dynamickými kurzory. Aktualizace provedené mimo kurzor nejsou viditelné, dokud nebudou potvrzeny (pokud není nastavena úroveň izolace transakce kurzoru UNCOMMITTED).
Předpokládejme například, že dynamický kurzor načte dva řádky a jiná aplikace pak aktualizuje jeden z těchto řádků a odstraní druhý. Pokud dynamický kurzor načte tyto řádky, nenajde odstraněný řádek, ale zobrazí nové hodnoty aktualizovaného řádku.
FAST_FORWARD
Určuje FORWARD_ONLYREAD_ONLY kurzor s povolenými optimalizacemi výkonu.
FAST_FORWARD nelze zadat, pokud SCROLL nebo FOR_UPDATE je také zadán. Tento typ kurzoru neumožňuje úpravy dat uvnitř kurzoru.
Note
Obě FAST_FORWARD a FORWARD_ONLY lze je použít ve stejném DECLARE CURSOR příkazu.
READ_ONLY
Zabrání aktualizacím provedeným tímto kurzorem. Kurzor nelze odkazovat v WHERE CURRENT OF klauzuli v klauzuli nebo UPDATEDELETE příkazu. Tato možnost přepíše výchozí funkci kurzoru, která se má aktualizovat.
SCROLL_LOCKS
Určuje, že umisťované aktualizace nebo odstranění provedené kurzorem jsou zaručeny úspěšné. SQL Server uzamkne řádky při jejich čtení do kurzoru, aby se zajistila jejich dostupnost pro pozdější úpravy.
SCROLL_LOCKS nelze zadat, pokud FAST_FORWARD nebo STATIC je také zadán.
OPTIMISTIC
Určuje, že umístěné aktualizace nebo odstranění provedené kurzorem nebudou úspěšné, pokud byl řádek aktualizován od jeho načtení do kurzoru. SQL Server nezamkne řádky při jejich čtení do kurzoru. Místo toho používá porovnání hodnot sloupců časového razítka nebo kontrolní součet, pokud tabulka nemá žádný sloupec časového razítka , k určení, zda byl řádek změněn po přečtení do kurzoru.
Pokud byl řádek změněn, pokus o umístění aktualizace nebo odstranění selže.
OPTIMISTIC nelze zadat, pokud FAST_FORWARD je zadán také.
Pokud STATIC je zadán spolu s argumentem kurzoru OPTIMISTIC , kombinace těchto dvou se implicitně převede na ekvivalent kombinace použití STATIC a READ_ONLY argumentů nebo STATIC argumentů FORWARD_ONLY .
TYPE_WARNING
Určuje, že se klientovi odešle zpráva s upozorněním, když je kurzor implicitně převeden z požadovaného typu na jiný.
Při použití kombinace OPTIMISTIC argumentů a STATIC argumentů kurzoru se klientovi neposílají žádná upozornění a kurzor se implicitně převede na ekvivalent kurzoru STATIC READ_ONLY nebo STATIC FORWARD_ONLY kurzoru. Převod, který se READ_ONLY změní na FAST_FORWARDREAD_ONLY kurzor z pohledu klientů.
select_statement
Standardní SELECT příkaz, který definuje sadu výsledků kurzoru. Klíčová slova COMPUTE, COMPUTE BY, FOR BROWSEa INTO nejsou povoleny v rámci select_statement deklarace kurzoru.
Note
V deklaraci kurzoru můžete použít nápovědu dotazu. Pokud však použijete také klauzuli FOR UPDATE OF , zadejte OPTION (<query_hint>) za FOR UPDATE OF.
SQL Server implicitně převede kurzor na jiný typ, pokud klauzule v select_statement konfliktu s funkcemi požadovaného typu kurzoru.
FOR UPDATE [ OF column_name [ ,... n ] ]
Definuje aktualizovatelné sloupce v kurzoru. Pokud OF <column_name> [, <... n>] je zadáno, povolují úpravy pouze sloupce uvedené v seznamu. Pokud UPDATE je zadána bez seznamu sloupců, lze aktualizovat všechny sloupce, pokud READ_ONLY nebyla zadána možnost souběžnosti.
Remarks
DECLARE CURSOR definuje atributy kurzoru serveru Transact-SQL, například jeho chování při posouvání a dotaz použitý k sestavení sady výsledků, na které kurzor pracuje. Příkaz OPEN naplní sadu výsledků a FETCH vrátí řádek ze sady výsledků. Příkaz CLOSE uvolní aktuální sadu výsledků přidruženou k kurzoru. Příkaz DEALLOCATE uvolní prostředky používané kurzorem.
První forma DECLARE CURSOR příkazu používá syntaxi ISO pro deklarování chování kurzoru. Druhá forma DECLARE CURSOR použití Transact-SQL rozšíření, která umožňují definovat kurzory pomocí stejných typů kurzorů používaných ve funkcích kurzoru rozhraní API databáze ROZHRANÍ ODBC nebo ADO.
Nemůžete kombinovat dvě formy. Pokud před klíčovým slovem zadáte SCROLL klíčová slova nebo INSENSITIVE klíčová CURSOR slova, nemůžete mezi klíčovými CURSOR slovy a FOR <select_statement> klíčovými slovy použít žádná klíčová slova. Pokud zadáte klíčová slova mezi CURSOR klíčovými slovy a FOR <select_statement> klíčovými slovy, nemůžete zadat SCROLL ani INSENSITIVE před klíčovým slovem CURSOR .
DECLARE CURSOR Pokud syntaxe using Transact-SQL nezadá READ_ONLY, OPTIMISTICnebo SCROLL_LOCKSje výchozí hodnota následující:
Pokud příkaz
SELECTnepodporuje aktualizace (nedostatečná oprávnění, přístup ke vzdáleným tabulkám, které nepodporují aktualizace atd.), kurzor jeREAD_ONLY.STATICaFAST_FORWARDkurzory mají výchozí hodnotuREAD_ONLY.DYNAMICaKEYSETkurzory mají výchozí hodnotuOPTIMISTIC.
Na názvy kurzorů lze odkazovat pouze jinými příkazy Transact-SQL. Na tyto funkce není možné odkazovat funkcemi rozhraní API databáze. Například po deklarování kurzoru nelze na název kurzoru odkazovat z funkcí OLE DB, ODBC nebo ADO nebo metod. Řádky kurzoru nelze načíst pomocí funkcí načtení nebo metod rozhraní API; řádky lze načíst pouze Transact-SQL FETCH příkazy.
Po deklaraci kurzoru lze tyto systémové uložené procedury použít k určení charakteristik kurzoru.
| Systémové uložené procedury | Description |
|---|---|
| sp_cursor_list | Vrátí seznamkurzorch |
| sp_describe_cursor | Popisuje atributy kurzoru, například to, jestli se jedná o kurzor jen dopředu nebo posouvání kurzoru. |
| sp_describe_cursor_columns | Popisuje atributy sloupců v sadě výsledků kurzoru. |
| sp_describe_cursor_tables | Popisuje základní tabulky, ke které přistupuje kurzor. |
Proměnné lze použít jako součást select_statement , která deklaruje kurzor. Hodnoty proměnných kurzoru se po deklaraci kurzoru nemění.
Permissions
Oprávnění výchozího DECLARE CURSOR nastavení pro každého uživatele, který má SELECT oprávnění k zobrazením, tabulkám a sloupcům použitým v kurzoru.
Limitations
V tabulce s clusterovaným indexem columnstore nemůžete použít kurzory ani triggery. Toto omezení neplatí pro neclusterované indexy columnstore. V tabulce s neclusterovaným indexem columnstore můžete použít kurzory a triggery.
Examples
A. Použití základního kurzoru a syntaxe
Sada výsledků vygenerovaná při otevření tohoto kurzoru zahrnuje všechny řádky a všechny sloupce v tabulce. Tento kurzor lze aktualizovat a všechny aktualizace a odstranění jsou reprezentovány při načítání provedených proti tomuto kurzoru.
FETCH NEXT je jediným dostupným načtením, protože není zadána SCROLL možnost.
DECLARE vend_cursor CURSOR
FOR SELECT * FROM Purchasing.Vendor
OPEN vend_cursor
FETCH NEXT FROM vend_cursor;
B. Použití vnořených kurzorů k vytvoření výstupu sestavy
Následující příklad ukazuje, jak lze vnořit kurzory pro vytváření složitých sestav. Vnitřní kurzor je deklarován pro každého dodavatele.
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;