MySQL giver os muligheden for at oprette lagrede procedurer . Lagrede procedurer er en stærk del af MySQL (og andre databasestyringssystemer, såsom SQL Server), og de giver dig mulighed for at gøre mere, end visninger gør.
En lagret procedure er en samling af SQL-sætninger, der er gemt i databasen. En lagret procedure kan indeholde forretningslogik, som er et af de centrale aspekter, der adskiller lagrede procedurer fra visninger. En lagret procedure kan acceptere parametre, og du kan indstille variabler, skrive IF
erklæringer osv. inden for en lagret procedure.
Hvordan fungerer lagrede procedurer?
Først og fremmest opretter du den lagrede procedure. Så når det er oprettet, kan du køre det (eller mere præcist, du "kalder" det).
For at køre en lagret procedure "kalder" du den. Når du kalder det, angiver du også de parametre, som det måtte kræve. Den lagrede procedure vil derefter udføres ved at bruge dine parametre på den måde, som koden specificerer.
For eksempel kan du skrive en lagret procedure, der accepterer en FruitId
parameter. Den lagrede procedure kunne derefter tage denne parameter og bruge den til at kontrollere beholdningen for den pågældende frugt. Derfor kan du kalde den lagrede procedure, hver gang med et andet frugt-id, og det ville returnere en værdi, der viser dig, hvor meget af den frugt, der er på lager.
Opret en lagret procedure
Lagrede procedurer oprettes ved hjælp af CREATE PROCEDURE
erklæring.
Syntaks
Her er syntaksen til at oprette en lagret procedure:
CREATE PROCEDURE sp_name(p_1 INT) BEGIN ...code goes here... END;
Erstat sp_name med hvilket navn du vil bruge til den lagrede procedure. Parenteserne er påkrævet - de omslutter alle parametre. Hvis der ikke kræves parametre, kan parentesen være tomme.
Hoveddelen af den lagrede procedure går mellem BEGIN
og END
søgeord. Disse nøgleord bruges til at skrive sammensatte udsagn. En sammensat sætning kan indeholde flere sætninger, og disse kan indlejres, hvis det kræves. Derfor kan du indlejre BEGIN
og END
blokke.
I de fleste tilfælde skal du også omgive CREATE PROCEDURE
sætning med DELIMITER
kommandoer og ændre END;
til END //
. Sådan:
DELIMITER // CREATE PROCEDURE sp_name(p_1 INT) BEGIN ...code goes here... END // DELIMITER ;
Jeg vil snart forklare hvorfor, men lad os nu se på et eksempel.
Eksempel
Her er et simpelt eksempel på oprettelse af en lagret procedure. Kører følgende kode mod vores FruitShop databasen vil oprette en lagret procedure kaldet spCheckFruitStock :
DELIMITER // CREATE PROCEDURE spCheckFruitStock(thisFruit SMALLINT) BEGIN SELECT Fruit.FruitName, Fruit.Inventory, Units.UnitName FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = thisFruit; END // DELIMITER ;
Nu kan vi kalde den lagrede procedure sådan her:
CALL spCheckFruitStock(1);
Her sender vi parameteren 1
som er ID'et for
Apple
.
Her er resultatet:
Vi kan gøre det samme for enhver frugt i vores database, blot ved at ændre parameteren, der er sendt til den lagrede procedure.
Om DELIMITER
Kommando
I ovenstående eksempel tilføjede vi et par DELIMITER
kommandoer, og vi erstattede et semikolon med to skråstreger. Hvad sker der her?
Vi gjorde dette for at fortælle MySQL at bruge en anden afgrænser, mens den opretter vores lagrede procedure.
Grunden til dette er, at MySQL allerede genkender semikolon som et afgrænsningstegn til markering af slutningen af hver SQL-sætning. Så snart MySQL ser det første semikolon, vil det derfor fortolke afgrænseren som sådan, og vores lagrede procedure ville bryde.
DELIMITER
kommandoen giver os mulighed for at fortælle MySQL at bruge en anden afgrænser. I ovenstående eksempel satte vi dette til to skråstreger (//
), men dette kunne have været hvad som helst (undgå dog at bruge en omvendt skråstreg (\
), da det er flugtkarakteren til MySQL). Ved at ændre afgrænsningstegnet vil MySQL ikke forsøge at fortolke vores semikolon som slutningen af sætningen – den vil vente, indtil den ser de to skråstreger frem.
Når vi har oprettet den lagrede procedure, kan vi bruge DELIMITER ;
for at nulstille afgrænsningstegnet tilbage til semikolon.
Sletning af en lagret procedure
Du kan droppe en lagret procedure ved at bruge DROP PROCEDURE
udmelding. Sådan:
DROP PROCEDURE spCheckFruitStock;
Ændring af en lagret procedure
Du kan ændre nogle aspekter af en lagret procedure ved at bruge ALTER PROCEDURE
udmelding.
Men for at ændre indholdet af den lagrede procedure eller nogen af dens parametre, skal du droppe proceduren og oprette den igen. Sådan:
DROP PROCEDURE IF EXISTS spCheckFruitStock; DELIMITER // CREATE PROCEDURE spCheckFruitStock(thisFruit SMALLINT) BEGIN SELECT Fruit.FruitId, Fruit.FruitName, Fruit.Inventory, Units.UnitName FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = thisFruit; END // DELIMITER ;
Her tilføjede vi Fruit.FruitId
til listen over kolonner, der skal returneres.
Resultat:
En mere avanceret lagret procedure
Ovenstående eksempel var simpelt for at demonstrere syntaksen ved at oprette og kalde lagrede procedurer. Lad os se på en lidt mere kompleks lagret procedure:
DROP PROCEDURE IF EXISTS spCheckFruitStockLevel; DELIMITER // CREATE PROCEDURE spCheckFruitStockLevel( IN pFruitId SMALLINT(5), OUT pStockLevel VARCHAR(6)) BEGIN DECLARE stockNumber SMALLINT; SELECT Fruit.Inventory into stockNumber FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = pFruitId; IF stockNumber > 10 THEN SET pStockLevel = 'High'; ELSEIF (stockNumber <= 10 AND stockNumber >= 5) THEN SET pStockLevel = 'Medium'; ELSEIF (stockNumber < 5) THEN SET pStockLevel = 'Low - Please Replace Now!'; END IF; END // DELIMITER ;
Ovenstående eksempel accepterer to forskellige tilstande af parametre (IN
og OUT
). IN
er standard, så det er grunden til, at det forrige eksempel ikke inkluderede tilstanden.
Her sætter vi også en variabel. Vi bruger DECLARE stockNumber SMALLINT
at erklære en variabel kaldet stockNumber
med en type SMALLINT
(lille heltal).
Vi bruger en SELECT
erklæring for at slå opgørelsen op for det givne frugt-id og tildele det til vores stockNumber
variabel.
Til sidst bruger vi en SQL IF
erklæring for at bestemme lagerniveauet ved at placere denne værdi i pStockLevel
parameter (som selvfølgelig er OUT
parameter — dette er den værdi, vi vil se, når vi kalder den lagrede procedure).
Opkald til en lagret procedure med en OUT
eller INOUT
Parameter
I vores sidste eksempel specificerede vi to parametre, en IN
parameter og en OUT
parameter.
Når vi kalder denne lagrede procedure, skal vi stadig inkludere OUT
parameter. Men fordi vi ikke kender dens værdi (det er trods alt derfor, vi kalder den - for at finde ud af dens værdi!), bliver vi nødt til at bruge en variabel. Så kan vi bruge en SELECT
erklæring for at finde ud af dens værdi.
Sådan:
CALL spCheckFruitStockLevel(1, @stockLevel); select @stockLevel;
Resultat:
Parametertilstande
Vi har lige brugt to parametertilstande (IN
og OUT
). I MySQL er der tre parametertilstande, der kan bruges med lagrede procedurer.
- IN
- Når du bruger denne parametertilstand, skal du (eller din applikation) videregive parameterens værdi, når du kalder den lagrede procedure. Disse parametre er beskyttet. Derfor bibeholdes dens oprindelige værdi, efter at den lagrede procedure er blevet udført. Hvis den lagrede procedure ændrer værdien, sker det kun på en kopi af parameteren.
Denne tilstand er standardtilstanden. Hvis du ikke angiver parametertilstanden, vil den være
IN
. - UD
- Værdien af en
OUT
parameter kan ændres inden for den lagrede procedure, og dens værdi returneres til den kaldende applikation. - INOUT
- Denne tilstand er en kombination af
IN
ogOUT
tilstande. Du kan videregive startværdien, den lagrede procedure kan ændre den, og den vil returnere den nye værdi til den kaldende applikation.