I SQL fungerar markörer som en pekare som gör det möjligt för applikationsprogrammeringsspråk att hantera frågeresultat en rad i taget. Den här artikeln utforskar snabbt konceptet bakom och visar hur man deklarerar markörer, öppnar, hämtar data från dem och sedan stänger dem.
SQL-markörer
Data i relationsdatabasen hanteras i form av set. Som ett resultat hänvisas frågeresultat som returneras av SQL SELECT-satser till som resultatuppsättningar. Resultatuppsättningarna är inget annat än kombinationer av en eller flera rader och kolumner extraherade från en eller flera tabeller. Du kan bläddra igenom resultatuppsättningarna för att extrahera den information du behöver. Dataelementen som returneras används av programmeringsspråk som Java eller något annat för specifika tillämpningsändamål. Men här ligger problemet med impedansfelanpassning på grund av skillnaden i konstruktion mellan databasmodell och programmeringsspråksmodell.
En SQL-databasmodell har tre huvudkonstruktioner:
- kolumner (eller attribut) och deras datatyper
- rader (skivor eller tupler)
- tabeller (samling av poster)
Därför är den primära oöverensstämmelsen mellan två modeller:
- De attributdatatyper som är tillgängliga i databasmodellen är inte desamma som de variabeltyper som används i programmeringsspråk. Det finns många värdspråk, och alla har olika datatyp. Till exempel är datatyperna för C/C++ och Java olika och det är även SQL-datatyperna. Därför är en bindande mekanism nödvändig för att mildra inkompatibilitetsproblemet.
- Resultatet som returneras av SQL SELECT-satser är flera uppsättningar av poster där varje post är en samling attribut. Värdprogrammeringsspråk fungerar vanligtvis på individuella datavärden för tuple som returneras av frågan. Därför är det viktigt att SQL-frågeresultat mappas med datastrukturen som stöds av programmeringsspråket. Mekanismen för att loopa över tuplar är nödvändig för att iterera över tupler och deras attributvärden.
Markören fungerar som en iteratorvariabel för att loopa över tupler som returneras av SQL-frågan och extrahera individuella värden inom varje tupel som sedan kan mappas till lämplig typ av programvariabler.
Markören fungerar därför som en pekare som gör det möjligt för programmeringsspråket att bearbeta frågeresultat en post i taget. En markör kan gå igenom alla rader i ett frågeresultat med fokus på en rad i taget. Tänk på följande SQL-fråga:
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);
Frågeresultatet från ovanstående uttalande returnerar personaluppgifter för alla de anställda vars födelsedatum infaller på den aktuella dagen i en viss månad. Resultatet kan innehålla många rader, men värdapplikationsspråket kan hantera en rad i taget. Som ett resultat deklareras markören som en inbäddad SQL-sats i applikationens programmeringsspråk. Markören öppnas sedan ungefär som en fil och extraherar en rad från frågeresultatet. Andra rader extraheras därefter, i följd tills markören stängs.
Deklarera en markör
Markörer deklareras ungefär som en variabel. Ett namn ges, det finns satser för att öppna markören, hämta frågeresultatet och slutligen stänga markören. Observera att olika SQL-implementationer stödjer användningen av markörer på olika sätt. Men det råder en allmän överenskommelse om hur markören ska skrivas.
Vi måste använda SQL-satser för att fullt ut implementera markörfunktionalitet eftersom det inte räcker att bara deklarera en markör för att extrahera data från en SQL-databas. Det finns fyra grundläggande steg för att deklarera en markör:
DEKLARERA MARKÖR: Deklarationen börjar med att ge markören ett namn och tilldela frågeuttrycket som ska anropas när markören öppnas.
ÖPPEN: Open-satsen kör det tilldelade frågeuttrycket och gör frågeresultatet klart för efterföljande FETCH.
HÄMTNING: Hämtar datavärden till variabler som sedan kan skickas till värdprogrammeringsspråket eller till andra inbäddade SQL-satser.
STÄNG: Markören är stängd från att hämta fler frågeresultat.
Syntaxen är som följer:
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>]}]
Den väsentliga delen av en markördeklaration är följande:
DECLARE <cursor_name> FOR <sql_query_expression>
Den valfria delen såsom [SENSITIVE | INSENSITIV | ASENSITIVE] anger om markören är känslig för ändringar och om de ska återspeglas i frågeresultatet. SENSITIVE betyder att markören påverkas av ändringar, INSENSITIVE betyder att markören inte påverkas och ASENSITIVE betyder att ändringar kan eller kanske inte är synliga för markören. Om det inte anges antar det ASENSITIVE alternativet.
Den valfria [SCROLL | NOSCROLL] definierar markörens rullningsförmåga. Om det inte anges antar det alternativet INGEN SCROLL.
Den valfria [ WITH HOLD | WITHOUT HOLD] definierar om den ska hållas eller stängas automatiskt när transaktionen på grund av markören genomförs. Om det inte anges behåller det alternativet WITHOUT HOLD.
Den valfria [ MED RETUR | WITHOUT RETURN] bestämmer om markörresultatuppsättningen ska returneras till anroparen, såsom en annan SQL-rutin eller värdspråk. Om det inte anges betyder det UTAN RETUR.
ORDER BY-satsen används för att sortera frågeresultatet som returneras enligt den specificerade sorteringstekniken.
Alternativet UPDATE hänvisar till användningen av UPDATE- eller DELETE-satsen associeras med raderna som returneras av markörens SELECT-sats. En sådan modifiering är inte möjlig om vi anger alternativet ENDAST läs. Om det inte anges antas alternativet UPPDATERING som standard.
Därför kan en enkel markör deklareras enligt följande:
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);
Markörer i MySQL
Vanligtvis finns det två typer av markörer i MySQL:skrivskyddade och endast framåtriktade markörer. Dessa markörer kan användas för MySQL-lagrade procedurer. Dessa markörer hjälper oss att iterera över frågeresultat en rad i taget och hämta in variabler för vidare bearbetning. Det är möjligt att deklarera mer än en markör och kapsla dem i loopar. Observera att markörer är skrivskyddade eftersom de används för att iterera över tillfälliga tabeller. Markören kör vanligtvis frågan när vi öppnar den.
Ett av problemen med markören i MySQL är att de kan sakta ner prestandan för frågan på grund av extra I/O-operationer de utför. Detta är särskilt för stora datatyper som BLOB och TEXT. Eftersom markörer fungerar med tillfälliga tabeller, stöds inte dessa typer i tabeller i minnet. Därför, när jag arbetar med dessa typer måste MySQL skapa tillfälliga tabeller på disken och det kräver mycket I/O-drift och det också i långsamma enheter som diskar. Detta är den främsta orsaken till långsam prestanda för markören.
MySQL stöder inte heller markörer på klientsidan, men klientens API kan emulera dem om det behövs. Men då skiljer det sig inte så mycket från att hämta resultatet i en array i programmeringsspråk som Java och manipulera dem där istället.
Här är ett exempel på hur man skriver markörer i 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
Anropa den lagrade proceduren enligt följande:
mysql> CALL cursor_demo
Proceduren hämtar raderna från en tabell som heter anställd vars födelsedatum matchar den aktuella dagen och månaden i en markör som heter mycursor och skriver helt enkelt ut dem med SELECT-satsen.
Se MySQL-dokumentationen på markören för mer information.
Slutsats
Markörer är inget annat än pekare till de uppsättningar poster som returneras av SQL-frågan. Pekaren pekar vanligtvis på en rad i taget och kan passeras i en slinga för att hämta individuella poster. SQL används normalt för direkt anrop för att komma åt och skapa dataobjekt. Markörerna tillhandahåller tekniken för interaktiv SQL där den möjliggör ad hoc exekvering av SQL-satser som underlättas genom klientapplikation. Markörens mekanism utnyttjar dataåtkomstmodellen där SQL-satser är inbäddade i värdspråk som C, C++ eller Java etc. Detta är bara en glimt av vad markören handlar om till att börja med. Se lämplig SQL-databasdokumentation för detaljer om specifika normer för olika implementeringar.
# # #