V SQL slouží kurzory jako ukazatel, který umožňuje aplikačnímu programovacímu jazyku pracovat s výsledky dotazů po jednom řádku. Tento článek rychle prozkoumá základní koncept a ukazuje, jak deklarovat kurzory, otevírat je, získávat z nich data a poté je zavírat.
Kurzory SQL
Data v relační databázi jsou spravována ve formě sad. V důsledku toho se výsledky dotazu vrácené příkazy SQL SELECT označují jako sady výsledků. Výsledné sady nejsou nic jiného než kombinace jednoho nebo více řádků a sloupců extrahovaných z jedné nebo více tabulek. Můžete procházet sady výsledků a extrahovat informace, které potřebujete. Vrácené datové prvky jsou používány programovacími jazyky, jako je Java nebo jakýkoli jiný, pro specifické aplikační účely. Zde ale spočívá problém nesouladu impedance kvůli rozdílu v konstrukci mezi databázovým modelem a modelem programovacího jazyka.
Databázový model SQL má tři hlavní konstrukce:
- sloupce (nebo atributy) a jejich datové typy
- řádky (záznamy nebo n-tice)
- tabulky (sbírka záznamů)
Primární nesoulad mezi dvěma modely je tedy:
- Datové typy atributů dostupné v databázovém modelu nejsou stejné jako typy proměnných používané v programovacích jazycích. Hostitelských jazyků je mnoho a každý má jiný datový typ. Například datové typy C/C++ a Java se liší, stejně jako datové typy SQL. Ke zmírnění problému s nekompatibilitou je proto nezbytný mechanismus vazby.
- Výsledkem vráceným příkazy SQL SELECT jsou vícenásobné sady záznamů, kde každý záznam je kolekcí atributů. Hostitelské programovací jazyky obvykle pracují na jednotlivých hodnotách dat n-tice vrácených dotazem. Proto je nezbytné, aby výsledek dotazu SQL mapoval s datovou strukturou podporovanou programovacím jazykem. Mechanismus smyčkování přes n-tice je nezbytný pro iteraci n-tic a jejich hodnot atributů.
Kurzor funguje jako proměnná iterátoru pro smyčkování n-tic vrácených dotazem SQL a extrahování jednotlivých hodnot v rámci každé n-tice, které pak lze mapovat na vhodný typ programových proměnných.
Kurzor tedy slouží jako ukazatel, který umožňuje programovacímu jazyku zpracovávat výsledky dotazu jeden záznam po druhém. Kurzor může procházet všemi řádky výsledku dotazu se zaměřením na jeden řádek najednou. Zvažte následující SQL dotaz:
SELECT emp_no, first_name, last_name, birth_date FROM employees WHERE MONTH(birth_date) = MONTH(CURRENT_DATE) AND DAY(birth_date) = DAY(CURRENT_DATE);
Výsledek dotazu z výše uvedeného výpisu vrátí údaje o zaměstnancích všech těch zaměstnanců, jejichž datum narození připadá na aktuální den určitého měsíce. Výsledek může obsahovat mnoho řádků, ale jazyk hostitelské aplikace může pracovat s jedním řádkem najednou. V důsledku toho je kurzor deklarován jako vložený příkaz SQL v rámci aplikačního programovacího jazyka. Kurzor se pak otevře podobně jako soubor a extrahuje jeden řádek z výsledku dotazu. Další řádky jsou extrahovány postupně, v pořadí, dokud se kurzor nezavře.
Deklarování kurzoru
Kurzory jsou deklarovány podobně jako proměnná. Je zadáno jméno, existují příkazy pro otevření kurzoru, načtení výsledku dotazu a nakonec zavření kurzoru. Všimněte si, že různé implementace SQL podporují použití kurzorů jiným způsobem. Ale panuje všeobecná shoda na tom, jak by měl být kurzor zapsán.
K plné implementaci funkce kurzoru musíme používat příkazy SQL, protože pouhé deklarování kurzoru nestačí k extrahování dat z databáze SQL. Existují čtyři základní kroky, jak deklarovat kurzor:
DEKLAROVAT KURZOR: Deklarace začíná zadáním názvu kurzoru a přiřazením výrazu dotazu, který se má vyvolat při otevření kurzoru.
OTEVŘÍT: Příkaz open provede přiřazený výraz dotazu a připraví výsledek dotazu pro následné FETCH.
NAČET: Načte hodnoty dat do proměnných, které pak mohou být předány hostitelskému programovacímu jazyku nebo jiným vloženým příkazům SQL.
ZAVŘÍT: Kurzor se zavře a nebude možné načíst žádný další výsledek dotazu.
Syntaxe je následující:
DECLARE <cursor_name> [SENSITIVE | INSENSITIVE | ASENSITIVE] [SCROLL | NO SCROLL] CURSOR [ WITH HOLD | WITHOUT HOLD] [ WITH RETURN | WITHOUT RETURN] FOR <sql_query_expression> [ ORDER BY <sort_expression>] [ FOR {READ ONLY | UPDATE [ OF <list_of_column>]}]
Podstatná část deklarace kurzoru je následující:
DECLARE <cursor_name> FOR <sql_query_expression>
Nepovinná část, jako je [SENSITIVE | NECITLIVÉ | ASENSITIVE] označuje, zda je kurzor citlivý na změny a zda je má zohlednit ve výsledku dotazu. SENSITIVE znamená, že kurzor je ovlivněn změnami, INSENSITIVE znamená, že kurzor není ovlivněn a ASENSITIVE znamená, že změny mohou, ale nemusí být pro kurzor viditelné. Pokud není specifikováno, předpokládá se volba ASENSITIVE.
Volitelné [SCROLL | NOSCROLL] definuje schopnost posouvání kurzoru. Pokud není specifikováno, předpokládá se volba NO SCROLL.
Volitelné [ WITH HOLD | WITHOUT HOLD] definuje, zda má být pozastaveno nebo automaticky uzavřeno, když je transakce kvůli kurzoru potvrzena. Pokud není zadáno, zachová se volba BEZ HOLD.
Volitelné [ WITH RETURN | WITHOUT RETURN] určuje, zda vrátit sadu výsledků kurzoru vyvolávajícímu, jako je jiná rutina SQL nebo hostitelský jazyk. Pokud není uvedeno, znamená to BEZ NÁVRATKU.
Klauzule ORDER BY se používá k řazení výsledku dotazu vráceného podle zadané techniky řazení.
Volba UPDATE odkazuje na použití příkazu UPDATE nebo DELETE, což je spojení s řádky vrácenými příkazem SELECT kurzoru. Jakákoli taková úprava není možná, pokud zadáme možnost POUZE PRO ČENÍ. Pokud není zadáno, pak se ve výchozím nastavení předpokládá možnost UPDATE.
Jednoduchý kurzor lze tedy deklarovat následovně:
DECLARE mycursor CURSOR FOR SELECT emp_no, first_name, last_name, birth_date FROM employees WHERE MONTH(birth_date) = MONTH(CURRENT_DATE) AND DAY(birth_date) = DAY(CURRENT_DATE);
Kurzory v MySQL
Typicky se v MySQL vyskytují dva typy kurzorů:kurzory pouze pro čtení a kurzory pouze pro předávání. Tyto kurzory lze použít pro uloženou proceduru MySQL. Tyto kurzory nám pomáhají iterovat výsledky dotazu jeden řádek po druhém a načítat je do proměnných pro další zpracování. Je možné deklarovat více než jeden kurzor a vnořit je do smyček. Všimněte si, že kurzory jsou jen pro čtení, protože se používají k iteraci přes dočasné tabulky. Kurzor obvykle provádí dotaz, když jej otevíráme.
Jedním z problémů kurzoru v MySQL je, že mohou zpomalit výkon dotazu kvůli dalším I/O operacím, které provádějí. To platí zejména pro skutečně velké datové typy, jako jsou BLOB a TEXT. Vzhledem k tomu, že kurzory pracují s dočasnými tabulkami, tyto typy nejsou podporovány v tabulkách v paměti. Proto při práci s těmito typy MySQL musí vytvářet dočasné tabulky na disku a to vyžaduje mnoho I/O operací a to také v pomalých zařízeních, jako jsou disky. Toto je hlavní důvod pomalého výkonu kurzoru.
MySQL také nepodporuje kurzory na straně klienta, ale klientské API je může v případě potřeby emulovat. Ale pak se to příliš neliší od načtení výsledku v poli v programovacím jazyce, jako je Java, a místo toho s nimi manipulovat.
Zde je ukázka, jak psát kurzory v MySQL.
CREATE PROCEDURE 'cursor_demo'() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE id INT(11); DECLARE fn varchar(14); DECLARE ln varchar(16); DECLARE bdate date; DECLARE mycursor CURSOR FOR SELECT emp_no, first_name, last_name, birth_date FROM employees WHERE MONTH(birth_date)=MONTH(CURRENT_DATE) AND DAY(birth_date)=DAY(CURRENT_DATE); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN mycursor; fetch_loop: LOOP FETCH mycursor INTO id, fn, ln, bdate; IF done THEN LEAVE fetch_loop; END IF; SELECT id, fn, ln, bdate; END LOOP; CLOSE mycursor; END
Zavolejte proceduru is uložená takto:
mysql> CALL cursor_demo
Procedura načte řádky z tabulky s názvem zaměstnanec jehož datum narození odpovídá aktuálnímu dni a měsíci v kurzoru s názvem mycursor a jednoduše je vytiskne pomocí příkazu SELECT.
Další informace naleznete v dokumentaci MySQL o kurzoru.
Závěr
Kurzory nejsou nic jiného než ukazatele na sady záznamů vrácených dotazem SQL. Ukazatel obvykle ukazuje vždy na jeden řádek a lze jej procházet ve smyčce a načítat jednotlivé záznamy. SQL se běžně používá pro přímé vyvolání pro přístup a vytváření datových objektů. Kurzory poskytují techniku interaktivního SQL, kde umožňují ad hoc provádění příkazů SQL usnadněných klientskou aplikací. Mechanismus kurzoru využívá model přístupu k datům, kde jsou příkazy SQL zabudovány do hostitelského jazyka, jako je C, C++ nebo Java atd. Toto je jen letmý pohled na to, s čím kurzor začíná. Podrobnosti o konkrétních normách různých implementací naleznete v dokumentaci příslušné databáze SQL.
# # #