Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
KiadtaRebeka Szilágyiné Megváltozta több, mint 6 éve
1
Sapientia - Erdélyi Magyar TudományEgyetem (EMTE)
ABR 2( Adatbázisrendszerek 2) 3. Előadás: Tárolt eljárások (folytatás) Nézetek
2
Kurzorok A kurzorok használata támogatott a tárolt rutinok, triggerek és események belsejében. A szintaxis beépül az SQL-be. A MySQL kurzoroknak a következő tulajdonságai vannak: Nem szenzitív: A szerver másolatot készíthet vagy sem az eredmény táblákból Read only: Nem írható felül Nem szkrollozható: Csak egy irányba lehet feldolgozni és nem lehet kihagyni egy sort sem A kurzorokat deklarálni kell, mielőtt deklaráljuk a handlereket. Változókat és feltételeket a kurzorok vagy handlerek előtt kell deklaráli.
3
CREATE PROCEDURE curdemo()
BEGIN DECLARE done INT DEFAULT 0; DECLARE a CHAR(16); DECLARE b,c INT; DECLARE cur1 CURSOR FOR SELECT id, data FROM test.t1; DECLARE cur2 CURSOR FOR SELECT i FROM test.t2; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur1; OPEN cur2; REPEAT FETCH cur1 INTO a, b; FETCH cur2 INTO c; IF NOT done THEN IF b < c THEN INSERT INTO test.t3 VALUES (a,b); ELSE INSERT INTO test.t3 VALUES (a,c); END IF; END IF; UNTIL done END REPEAT; CLOSE cur1; CLOSE cur2; END
4
DECLARE cursor_name CURSOR FOR select_statement Ez az utasítás deklarál egy kurzort. Többszörös kurzor deklarációja lehetséges egy tárolt programban, de minden kurzor egy adott blokkon belül egyedi névvel kell rendelkezzen. A SELECT utasításnak nem lehet INTO záradéka. OPEN cursor_name Ez az utasítás megnyit egy előzőleg deklarált kurzort. FETCH cursor_name INTO var_name [, var_name] ... Ez az utasítás behozza a következő sort (ha a sor létezik) használva a specifikált megnyitott kurzort és előreviszi a kurzor pointert. Ha már nincs elérhető sor, a No Data feltétel jelenik meg az SQLSTATE értékkel. Hogy kimutassuk ezt a feltételt, fel lehet állítani egy handlert hozzá. CLOSE cursor_name Ez az utasítás bezárja az előzőleg megnyitott kurzort. Ha nincs explicit bezárva, a kurzor bezáródik az összetett utasítás végével, ahol deklarálva volt.
5
Az IF utasítás IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list] ... [ELSE statement_list] END IF DELIMITER // CREATE FUNCTION SimpleCompare(n INT, m INT) RETURNS VARCHAR(20) BEGIN DECLARE s VARCHAR(20); IF n > m THEN SET s = '>'; ELSEIF n = m THEN SET s = '='; ELSE SET s = '<'; END IF; SET s = CONCAT(n, ' ', s, ' ', m); RETURN s; END // DELIMITER ;
6
DELIMITER // CREATE FUNCTION VerboseCompare (n INT, m INT) RETURNS VARCHAR(50) BEGIN DECLARE s VARCHAR(50); IF n = m THEN SET s = 'equals'; ELSE IF n > m THEN SET s = 'greater'; ELSE SET s = 'less'; END IF; SET s = CONCAT('is ', s, ' than'); SET s = CONCAT(n, ' ', s, ' ', m, '.'); RETURN s; END // DELIMITER ;
7
A CASE utasítás CASE case_value WHEN when_value THEN statement_list
[ELSE statement_list] END CASE Vagy: CASE WHEN search_condition THEN statement_list [WHEN search_condition THEN statement_list] ...
8
DELIMITER | CREATE PROCEDURE p() BEGIN DECLARE v INT DEFAULT 1; CASE v WHEN 2 THEN SELECT v; WHEN 3 THEN SELECT 0; ELSE END; END CASE; END; |
9
A LOOP és LEAVE utasítás
[begin_label:] LOOP statement_list END LOOP [end_label] LOOP implementál egy szimpla hurkot, amelyik lehetővé teszi a többszörös elvégzését egy utasítás listának, amelyik egy vagy több utasításból áll, mindenik egy (;)-vel végződik. A hurokban levő utasítások a hurokból való kilépésig hajtódnak végre; általában ez a LEAVE záradékkal fejeződik be. Egy LOOP utasítás cimkézhető. LEAVE utasítás LEAVE label Ez a záradék arra használható, hogy kilépjünk egy hurok kontroll konstrukcióból, amelyiknek egy adott cimkéje van. Használható a BEGIN...END belsejében vagy ugrási konstrukciókban (LOOP, REPEAT, WHILE)
10
Az ITERATE utasítás ITERATE label
ITERATE csak a LOOP, REPEAT és WHILE záradékokban jelenhet meg. ITERATE azt jelenti, hogy végezd a ciklust mégegyszer. Példa: CREATE PROCEDURE doiterate(p1 INT) BEGIN label1: LOOP SET p1 = p1 + 1; IF p1 < 10 THEN ITERATE label1; END IF; LEAVE label1; END LOOP label1; = p1; END
11
A REPEAT utasítás [begin_label:] REPEAT statement_list
UNTIL search_condition END REPEAT [end_label] Az utasítás listát egy REPEAT záradékon belül annyiszor ismételünk meg, amíg igaz marad a search_condition. Eképpen a REPEAT legalább egyszer belépik a ciklusba. A statement_list egy vagy több utasítást tartalmaz, mindenik pontosvessző utasítás elválasztóval végződik.
12
delimiter // CREATE PROCEDURE dorepeat(p1 INT) BEGIN = 0; REPEAT + 1; > p1 END REPEAT; END // CALL dorepeat(1000)// | |1001|
13
A WHILE utasítás [begin_label:] WHILE search_condition DO
statement_list END WHILE [end_label] Az utasítás lista a WHILE utasításon belül addíg hajtódik végre, amíg a search_condition igaz. statement_list egy vagy több utasításból áll. CREATE PROCEDURE dowhile() BEGIN DECLARE v1 INT DEFAULT 5; WHILE v1 > 0 DO ... SET v1 = v1 - 1; END WHILE; END
14
Előkészített utasítások (prepared statement)
Az SQL szintaxisa az előkészített utasításokra a következő három SQL utasításra épül: PREPARE elvégzésre készít elő egy utasítást. EXECUTE futtatja az utasítást. DEALLOCATE PREPARE felszabadítja az előkészített ut. PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; = 3; = 4; EXECUTE |hypotenuse| | | DEALLOCATE PREPARE stmt1;
15
Előkészített utasítások (prepared statement)
Ez az eset hasonló, csak helyettesíti az utasítás szövegét egy felhasználói változóval: = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; PREPARE stmt2 = 6; = 8; EXECUTE | hypotenuse | | | DEALLOCATE PREPARE stmt2;
16
Egy előkészített utasítás a session része, amelyben keletkeztették
Egy előkészített utasítás a session része, amelyben keletkeztették. Ha befejezünk egy sessiont és nem szabadítottuk fel az általa előkészített utasításokat, a szerver automatikusan felszabadítja. Egy előkészített utasítás globális egy session-ra. Ha készítünk egy előkészített utasítást egy tárolt rutinban, a rutin befejezése nem szabadítja fel azt. Hogy védekezzünk az ellen, hogy túl sok előkészített utasításunk legyen egyszerre, állítsuk be a max_prepared_stmt_count rendszer változót. Hogy letiltsuk az előkészített utasítások használatát, állítsuk be ezt az értéket 0-ra. A következő SQL utasítások használhatók az előkészített utasításokban: ALTER TABLE, CALL, COMMIT, CREATE INDEX, CREATE TABLE, DELETE, DO, DROP IDEX, DROP TABLE, INSERT, RENAME TABLE, REPLACE, SELECT, SET, UPDATE és a legtöbb SHOW utasítás. Az új verziók egyre több lehetőséget adnak az utasítások használatára, pl. Az esetén megvalósíthatók a : ANALYZE TABLE, OPTIMIZE TABLE és REPAIR TABLE.
17
A Prepare szintaxisa PREPARE stmt_name FROM preparable_stmt
A stmt_name nevű előkészített utasítás. Nem betűérzékeny. preparable_stmt egy sztring literál vagy egy felhasználói változó, amelyik tartalmazza az utasítás szövegét. A szöveg egyetlen SQL utasítást kell jelentsen, nem több utasítást. Az utasításokban a ? karaktereket használjuk, mint paraméter jelzőt, hogy megadjuk, hova kell a paamétereket beilleszteni a lekérdezésbe utólagosan, mikor futtatni szeretnénk. A ? karaktereket nem tesszük idézőjelbe, még akkor sem, ha sztring értékbe akarjuk beilleszteni. Paraméter jelzőket csak ott szabad használni, ahol adat-értékek tudnak megjelenni, nem SQL kulcsszavakat, azonosítókat vagy ehhez hasonlókat. Az előkészítő utasítás hatóköre az a session, ahol keletkezett. Más session nem látja ezeket.
18
EXECUTE és DEALLOCATE szintaxisa
EXECUTE stmt_name ...] Miután elkészítettük az előkészített utasítást a PREPARE segítégével, ezt futtatni az EXECUTE utasítással lehet, amelyik hivatkozik az előkészített utasítás nevére. Ha az előkészített utasítás tartalmaz paraméter jelzőket, kötelező a USING záradékban megadni a változók listáját azon értékekkel, amelyek beépülnek a paraméterekbe. Paraméterek értékét csak felhasználó változókkal helyettesíthetjük és a USING záradék pontosan ugyanannyi változót kell megnevezzen, mint amennyi paramétert jeleztünk az utasításban. Az előkészített utasítás többször elvégezhető, más-más változókat adva át, vagy beállítva a változókat külöböző értékekre az elvégzés előtt. {DEALLOCATE | DROP} PREPARE stmt_name
19
Nézettáblák Nem léteznek fizikailag az adatbázisban.
Egy lekérdezéshez hasonló kifejezés segítségével definiáljuk. Lekérdezésük ugyanolyan, mint a rendes tábláké. Bizonyos esetekben módosíthatjuk is őket. CREATE VIEW <név> AS <definíció>; Szeretnénk látni az ALFA Kft-nek számlázott összegeket. 1) CREATE VIEW AlfaKFT AS 2) SELECT SUM(kiszamla.osszeg) 3) FROM kiszamla INNER JOIN ugyfel ON kiszamla.ugyfelid=ugyfel.azonosito 4) WHERE ugyfel.nev=‘Alfa SRL’;
21
CREATE VIEW AlfaSzamla AS
SELECT szamlaszam, afa, datum, osszeg FROM kiszamla INNER JOIN ugyfel ON kiszamla.ugyfelid=ugyfel.azonosito WHERE ugyfel.nev=‘Alfa SRL’; Nem szerepel benne a hatarido és az ugyfelkod. Nézettáblák lekérdezése: SELECT SUM(alfaszamla.osszeg) FROM alfaszamla WHERE month(Datum)=2; Megadja a 2-ik hónapban összesen számlázott értéket.
22
A lekérdezés ekvivalens a következővel:
SELECT SUM(kiszamla.osszeg) FROM kiszamla INNER JOIN ugyfel ON kiszamla.ugyfelid=ugyfel.azonosito WHERE month(Datum)=2 AND ugyfel.nev=‘Alfa KFT’; Lekérdezés szempontjából úgy viselkedik, mintha tárolt alaptábla lenne. Lehet keverni az alaptáblákkal. SELECT alfaszamla.szamlaszam, termek.nev FROM alfaszamla, szamlasor, termek WHERE alfaszamla.szamlaszam=szamlasor.szamlaszam AND szamlasor.termekid=termek.termekid; Megadja, hogy az Alfa SRL melyik számlán milyen terméket adott el.
23
CREATE VIEW ugyfelTermek AS
SELECT ugyfel.nev AS ugyfelNev, termek.nev AS termekNev FROM ugyfel, kiszamla, szamlasor, termek WHERE kiszamla.ugyfelid=ugyfel.azonosito AND szamlasor.szamlaszam=kiszamla.szamlaszam AND szamlasor.termekid=termek.termekid; Szükséges volt az attribútumok átnevezése, mivel mindkettő nev volt. CREATE VIEW ugyfelTermek2(ugyfelNev,termekNev) AS SELECT ugyfel.nev, termek.nev Ekvivalens az előzővel, az átnevezés van máshol.
24
Adatmódosítás nézettáblákon keresztül
Korlátozott módon lehetséges beszúrni, törölni vagy változtatni. Egyszerű nézettáblák esetében a nézettábla módosítás átalakítható alaptábla módosítássá. Ezen nézettáblákat módosítható nézettábláknak nevezzük. DISTINCT nem szerepelhet a SELECT után WHERE záradékban R nem szerepelhet egy alkérdésben sem A SELECT záradék elég attribútumot kell tartalmazzon, hogy egy beszúrás esetén a többi attribútumot null értékkel, vagy az alapértelmezett értékkel tölthessük fel az alaptáblában. INSERT INTO alfaszamla(szamlaszam, afa,datum,osszeg) VALUES(3008,19,’ ’,0);
25
Nézettáblák MySQL-ben
A CREATE VEW utasítás egy új nézetet készít. Hogy módosítsuk a definícióját egy nézetnek vagy eldobjunk egy nézetet, hasznájuk az ALTER VIEW, vagy a DROP VIEW utasítást. Egy nézetet több féle SELECT utasítással lehet elkészíteni. Ez tartalmazhat alaptáblákat és más nézeteket. Használhat összekötéseket, UNION utasításokat és alkérdéseket. A SELECT nem szükségszerűen kell hivatkozzon táblákra. Az elkövetkező példa definiál egy nézetet, amelyik kiválaszt két oszlopot egy másik táblából és egy kifejezést, amelyet ezen két oszlopból számít ki: CREATE TABLE t (qty INT, price INT); INSERT INTO t VALUES(3, 50), (5, 60); CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t; SELECT * FROM v;
26
Nézetfeldolgozó algoritmusok
Az opcionális ALGORITHM záradék a CREATE VIEW vagy az ALTER VIEW esetre egy MySQL kiterjesztése a standard SQL-nek. Ez befolyásolja azt, hogyan dolgozza fel a MySQL a nézetet. ALGORITHM –nak három értéke lehet: MERGE, TEMPTABLE vagy UNDEFINED. Az alapértelmezett algoritmus az UNDEFINED ha semmilyen ALGORITHM záradék nem szerepel. MERGE esetében, az utasítás szövege, amelyik vonatkozik a nézetre és a nézet definíciója egyesül olyanformán, hogy a részei a nézet definíciónak helyettesítik a megfelelő részét az utasításnak. TEMPTABLE esetén az eredmények a nézetből egy temporális táblában tárolódnak, amelyeket majd az utasítás elvégzéséhez használjuk.
27
Az UNDEFINED esetében a MySQL választja ki, hogy melyik algoritmus legyen. Preferált a MERGE a TEMPTABLE helyett, ha lehetséges, mivel a MERGE általában sokkal hatékonyabb és egy nézeten keresztül nem lehet adatot módosítani, ha temporális táblát használunk. Egy ok a TEMPTABLE explicit használatára az, hogy zárakat lehet feloldani a háttérben levő táblákról, miután a temporális tábla elkészül és mielőtt használnánk, hogy befejezzük az utasítás feldolgozását. Ez jelenthet egy gyorsabb zárfeloldást, mint a MERGE algoritmusnál, vagyis más felhasználók, amelyek használják a nézetet nincsenek olyan sokáig blokkolva. Egy nézet algoritmus UNDEFINED három okból lehet: Ha nincs ALGORITHM záradék a CREATE VIEW utasításban. A CREATE VIEW záradékban explicit meg van adva az ALGORITHM = UNDEFINED záradék. ALGORITHM = MERGE van specifikálva egy olyan nézetben, amelyik csak temporális táblával tudja feldolgozni. Ebben az esetben a MySQL generál egy figyelmeztetést és átállítja az algoritmust UNDEFINED-re.
28
CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) AS
SELECT c1, c2 FROM t WHERE c3 > 100; 1 példa: Feltételezzük, hogy meghívjuk a köv. utasítást: SELECT * FROM v_merge; MySQL a következő képpen kezeli az utasítást: v_merge átalakul t-vé * átalakul vc1, vc2, amelyik megfelel a c1, c2-nek A nézet WHERE záradék hozzáadódik Az eredmény utasítás a következő lesz: 2 péla: SELECT * FROM v_merge WHERE vc1 < 100; vc1<100 átalakul c1<100 SELECT c1,c2 FROM t WHERE (c3>100) AND (c1<100);
29
MERGE algoritmus nem használható, ha a nézet tartalmaz egyet a következő konstrukciókból:
Összegző függvényeket (SUM(), MIN(), MAX(), COUNT() stb.) DISTINCT GROUP BY HAVING LIMIT UNION vagy UNION ALL Alkérdést a kiválasztott listában Csak literálokra hivatkozik (ez esetben nincsen háttérben tábla)
30
Módosítható és bevitelt megengedő nézetek
Egyes nézeteken keresztül módosíthatjuk az alaptábla adatait. Ez azt jelenti, hogy használjuk őket olyan utasításokban, mint UPDATE, DELETE vagy INSERT, hogy módosítsuk a háttérben levő tábla adatait. Hogy egy nézet módosításra legyen alkamas, egy-az egyhez tipusú kapcsolat kell legyen a nézet és az alaptábla sorai között. Vannak olyan konstrukciók, amelyek nem engedik a módosítást. Egy nézeten keresztül nem lehet módosítani, ha a következőket tartalmazza: Összesítő függvényeket (SUM(), MIN(), MAX(), COUNT()) DISTINCT GROUP BY
31
HAVING UNION vagy UNION ALL Alkérdést a kiválasztott listában Valódi JOIN-t Nem módosítható nézeteket a FROM záradékban Egy alkérdést a WHERE záradékban, amelyik vonatkoztat egy táblára a FROM záradékban Csak literálokra hivatkozik (ez esetben nincsen háttérben tábla) Használja az ALGORITHM = TEMPTABLE (temporális tábla használata mindíg módosítás-képtelen nézetet eredményez) Többszörös referencia bármely oszlopára az alap táblának A beszúráshoz még a következő feltételek kell teljesüljenek: Nem lehetnek egyforma oszlopnevek A nézetnek tartalmaznia kell minden oszlopot az alap táblából, amelyiknek nincs alapértelmezett értéke. A nézet oszlopok egyszerű oszlop referenciák kell legyenek és nem származtatottak. Egy származtatott oszlop az olyan, amelyik nem egy egyszerű oszlop hivatkozás, hanem származtatva van egy kifejezésből. Pl , col1 + 3 , UPPER(col2), col3 / col4 , (alkérdés)
32
Ha egy nézetben egyszerű oszlophivatkozások vannak és származtatott oszlopok, nem beszúrható nézet, viszont módosítható ha azon oszlopokat módosítjuk, amelyek nem származtatottak: CREATE VIEW v AS SELECT col1, 1 AS col2 FROM t; Ezen nézet nem beszúrható, mivel a col2 egy kifejezésből származik.Viszont ez módosítható, ha nem akarjuk módosítani a col2-ben levő adatoknak. Ez a módosítás elfogadható: UPDATE v SET col1 = 0; A következő módosítás nem elfogadható: UPDATE v SET col2 = 0; Néha lehetséges, hogy egy többszörös tábla nézet módosíthasson, ha a MERGE algoritmussal fel lehet dolgozni. Hogy ez működhessen, a nézet egy inner join kapcsolatban kell legyen (sem külső sem UNION). Ugyanakkor, csak az egyik táblát lehet módosítani, vagyis a SET záradék csak egy táblából levő oszlopot tartalmazzon a nézetben. Azon nézetek, amelyek használják az UNION ALL-t akkor sem módosíthatnak, ha elméletileg azok lennének, mivel az implementáció temporális táblákat tartalmaz. Több táblás nézetben az INSERT akkor működik, ha egy táblába történik beszúrás.
33
Több táblás nézetben a DELETE nem támogatott.
INSERT DELAYED nem támogatott a nézetekben. CREATE TABLE t1 (a INT); CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2 WITH CHECK OPTION; CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0 WITH LOCAL CHECK OPTION; CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0 WITH CASCADED CHECK OPTION; Itt a v2 és a v3 nézetek más nézetekre épülnek. v1.és v2-nek van egy LOCAL ellenőrzési (check) opciója, vagyis a beszúrások csak a v2-re vonatkoznak. V3-nak van egy CASCADED ellenőrzési opciója, tehát a beszúrások nem csak a saját feltételeket ellenőrzi, hanem mindeniket a háttérben levő nézetekből is. A következő utasítások bemutatják ezen különbségeket: mysql> INSERT INTO v2 VALUES (2); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO v3 VALUES (2); ERROR 1369 (HY000): CHECK OPTION failed 'test.v3‘
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.