• Nem Talált Eredményt

8. Lecke: MySQL-adatbázisok kezelése PHP-ben

8.6 DML INSERT

Új rekord beszúrása egy táblába legalább olyan egyszerű, mint a rekord módosítása. A végrehajtásban sincs nagy különbség, csupán az SQL-mondat lesz más. Mégis azt kell mondanunk, hogy a jól megtervezett adatbázisban az új rekordok fölvétele okozza a legtöbb gondot. Lássuk csak miért!

A redundancia kiküszöbölése érdekében az adatbázis tervezésekor olyan adatszerkezetet alakítunk ki, amely részleges és a tranzitív függésektől mentes.

Mivel a káros függések megszűntetésekor dekompozíciót alkalmazunk, még a kis adatbázisok is több táblákra bomlanak. A táblák közötti kapcsolatokat ide-gen kulcsok írják le.

A felhasználó ebből persze semmit sem lát. Amikor megadja egy könyv adatait, nem érdekli őt, hogy a kiadók, és a szerzők külön táblában tárolódnak és arra is fittyet hány, hogy a konyv és szerzo tábla N:M kapcsolat miatt kapcsolótáblára is szükség volt. Egy könyv összes adatát egyetlen űrlapon akarja begépelni. A programozónak természetesen olyan kezelőfelületet kell

előállíta-nia, amelyen a felhasználó kényelmesen dolgozhat, de a bejövő adatokat (meg-felelő ellenőrzés után) a különböző táblákban kell tárolnia, és az idegen kulcsok helyességéről is gondoskodnia kell.

Következő példánkban egy könyv adatait rögzítjük. Az egyszerűség kedvé-ért induljunk ki abból, hogy a bevitel megtörtént, az adatok eljutottak a szerver-re, és a validáláson is túlvagyunk. A rögzítendő adatokat a jobb áttekinthetőség kedvéért egy asszociatív tömbbe rendeztük:

$insert=array(

"kiado"=>array("kiNev"=>"Szak Kiadó Kft."), "szerzo"=>array("szNev"=>"Young, Michael J."), "konyv"=>array( re-kordjainak mezőnevei és értékeik. Az azonosítók mindenhonnan hiányoznak, ugyanis a táblában automatikus sorszámozású (AUTO_INCREMENT) mezők lesznek az azonosítók.

A fenti tömb csak az adatok átláthatóságát szolgálja, a példaprogra-mokban nem szerepel.

A feladatot a kiado táblával kell kezdenünk. Az új kiadó rekordjának be-szúrása nem fog nehézséget okozni, azonban nem szabad megfeledkezni arról, hogy szükségünk lesz az újonnan beszúrt rekord azonosítójára, hiszen ez idegen kulcsként fog szerepelni a konyv táblában.

A kiadó után fölvehetjük az új könyvet, majd a szerzőt, de ismét meg kell jegyeznünk azonosítókat, hiszen a kony_szerzo táblában idegen kulcsokkal kell jelezni az új könyv és az új szerző kapcsolatát.

Összesen tehát négy táblába kell rekordot elhelyeznünk. A nehézségeket tovább fokozza ez egyes műveletek esetén fennálló hibalehetőség.

Ha fel tudjuk venni az új könyvet és a szerzőt, de a konyv_szerzo tábla rekordjának beszúrásakor hiba keletkezik, akkor minden lépést vissza kellene vonnunk…

Töröljük az érintett táblából az utolsó rekordokat? Jó megoldás! ...Akkor, ha csak mi használjuk az adatbázist. A web alkalmazásnak azonban éppen az az

168 MySQL-adatbázisok kezelése PHP-ben

óriási előnye, hogy egyszerre többen is dolgozhatnak vele. Mi történik, ha a mi munkánk közben más is rögzített könyveket? Bizony ilyenkor az ő rekordjaikat törölnénk egy estleges visszalépéskor.

Szerencsére a MySQL InnoDB táblái tranzakcióbiztosak (a mi adatbázisunk táblái ilyenek), így nyugodtan használhatjuk a tranzakció kezelést!

Ehhez semmi egyebet nem kell tennünk, mint a mysql_query() függ-vénnyel, a megfelelő helyeken el kell küldenünk a "BEGIN", "COMMIT", illetve a "ROLLBACK" parancsokat.

Az első INSERT előtt a mysql_query("BEGIN"); függvényhívással elindítjuk a tranzakciót. Elvégezzük a rekordok beszúrását, de minden egyes INSERT-eknél külön változóban tároljuk az erőforrás azonosítót. A rekordfölvéltelek után megvizsgáljuk őket. Ha bármelyik erőforrás azonosító false, akkor visszagörgetjük a tranzakciót. Azaz minden INSERT-et

semmis-sé teszünk. Ha minden rendben ment, akkor egy

mysql_query("COMMIT")-tal zárjuk a műveleteket.

Valójában egyetlen problémánk maradt. Hogyan tudjuk meg az elsődleges táblákba beszúrt rekordok azonosítóit? A beszúrás utáni utolsó rekord azonosí-tójának lekérdezése az ismert okok miatt nem járható út. A MySQL API-ban azonban rendelkezésre áll a mysql_insert_id() függvény, amely a meg-adott kapcsolat legutolsó AUTO_INCREMENT értékét adja vissza.

egész mysql_insert_id ([erőforrás_id] )

Ezzel a függvénnyel már megtudhatjuk az egyes INSERT parancsokkal be-szúrt utolsó rekordok azonosítóit, hiszen a tábláink mindegyike AUTO_INCREMENT azonosítókat tartalmaz.

Forrás: mysql_query_insert.php

70. ábra Rekordok tranzakció biztos beszúrása

8.7 ÖSSZEFOGLALÁS, KÉRDÉSEK

8.7.1 Összefoglalás

Mai leckénkben a PHP MySQL API-jának legfontosabb függvényeit ismertük meg. Megtanultuk, hogy a MySQL-szerverek elérése a kapcsolat fölépítésével kezdődik, amit a mysql_connect() függvény hívásával végezhetünk el.

Ezután következik a mysql_select_db() indítása, azaz az adatbázis kivá-lasztása. A létrehozott SQL-mondatot, a myslq_query() függvénnyel küld-hetjük el az adatbázis-kezelő rendszernek, az eredményt pedig általában válto-zóba tesszük. A DQL-lekérdezések erőforrás azonosítóval, vagy false értékkel a DML-mondatok true, vagy false eredménnyel térnek vissza. A relációkat visszaadó lekérdezések rekordjait a mysql_fetch_row(), illetve a mysql_fetch_assoc() függvények ciklikus hívásával nyerhetjük ki.

A DML-mondatok végrehatása után csak arra kell figyelni, hogy a művelet sikeres volt-e. Ha adatbázisunk táblái tranzakció biztosak, a BEGIN, COMMIT, és ROLLBACK parancsok elküldésével valósíthatjuk meg tranzakció kezelést.

8.7.2 Önellenőrző kérdések

1. Hány MySQL kapcsolatot nyithatunk meg ugyanahhoz a szerverhez egy PHP-szkriptben?

170 MySQL-adatbázisok kezelése PHP-ben

 Általában egyet nyitunk, de több kapcsolatot is fölépít-hetünk. Tudni kell azonban, hogy a mysql_connect() többszöri meghívása esetén alapértelmezésben ugya-nazt a kapcsolat azonosítót adja vissza. Ha azonban a függvény negyedik paraméterként true értéket adunk meg, akkor minden hívás új kapcsolatot alakít ki.

2. Megmaradhat-e a kapcsolat, ha a mysql_connect() függvénytől ka-pott azonosítót munkamenet változóként tároljuk?

 Nem. A kapcsolat mindenképpen megszakad, amikor a PHP-szkript befejeződik.

3. Mire használható a mysql_set_charset() függvény?

 A MySQL-szervertől érkező válaszok karakterkódolá-sának szabályozására.

4. Hogyan törölhet rekordot egy táblából?

 A DELETE parancsot tartalmazó SQL-mondatot el kell küldeni a MySQL-szervernek, és megvizsgálni, hogy a mysql_query() függvény visszatérési értéke true, vagy false.

5. Hogyan tudja elérni, hogy az egymás után végrehajtott

DML-lekérdezésnek csak akkor legyen hatása, ha mindegyik végrehajtása sikeres volt?

 A lekérdezések elküldését tranzakción belül kell elvé-gezni. Ha bármelyik mysql_query() false eredményt ad vissza, ki kell adni a mysql_query(”ROLLBACK”); paran-csot. Ha minden DML-mondat sikeresen lefutott, akkor a mysql_query(”COMMIT”) hívással lehet jóváhagyni a tranzakciót.

9. LECKE: OBJEKTUMORIENTÁLT