Szerkesztő:Mkesmarki/sql
Structured Query Language: Strukturált lekérdező nyelv.
Angol nyelvterületen 'eszkjuel' a kiejtése. A hagyományokhoz való hűség jegyében sokan 'szíkvel'-nek ejtik, ugyanis korábban Structured English Query Language volt az elnevezés, és ezt rövidítették le.
A relációs adatbázis-kezelők általában az SQL nyelven programozhatók. Az SQL alapvető utasításait közel egyformán valósítják meg, de a később beépült nyelvi elemek körében nagyon nagy az eltérés, az inkompatíbilitás, emiatt számos SQL nyelvjárásról beszélhetünk.
Jellegét tekintve ez a programozási nyelv részben procedurális, részben deklaratív.
Az SQL története
szerkesztésAz SQL alapjait az IBM-nél fektették le, még az 1970-es években. Elvi alapot a relációs adatmodell szolgáltatott, amit Edgar F. Codd híres 12 szabályával írt le először, 1970-ben.
Az IBM, az Oracle és más gyártók is érdekeltek voltak egy szabványos lekérdező nyelv kifejlesztésében, amivel a relációs adatbázisok programozhatók. Az iparági összefogással létrejött ANSI NCITS (National Committee on Information Technology Standards) H2 csoport lerakta az SQL alapjait.
A szabványt az ANSI (Amerikai Nemzeti Szabványügyi Intézet - American National Standards Institute) 1986-ban, az ISO (Nemzetközi Szabványügyi Szervezet - International Organization for Standardization) 1987-ben jegyezte be. Az első változatot SQL86 néven is szokták emlegetni.
Az SQL-t folyamatosan továbbfejlesztették, és négy jelentős kiadást különböztetünk meg:
- SQL86
- SQL89
- SQL92
- SQL99
Az első kivételével mindegyik szabvány többszintű megvalósítást tesz lehetővé a gyártóknak (belépő szintű, közepes vagy teljes). Általában a későbbi szabványok belépő szintjei az előző szabvány teljes szintjeinek felelnek meg.
Az SQL nyelv
szerkesztésA nyelvi elemeket szokásos adatdefiníciós (Data Definition Language, DDL) és adatkezelési (Data Manipulation Language, DML) részekre bontani. A nyelvben az utasításokat a pontosvessző választja el egymástól.
Adatdefiníciós utasítások
szerkesztésCREATE
szerkesztésAdatbázis objektum létrehozása. Példa adatbázis tábla definíciójára:
CREATE TABLE Szamla ( Szamlaszam NUMERIC(24), Tulajdonos VARCHAR(60), Nyitas DATE, Allapot VARCHAR(1), PRIMARY KEY (Szamlaszam) );
A fenti példa létrehoz egy adatbázis táblát, 4 oszloppal.
ALTER
szerkesztésAdatbázis-objektum módosítása. Példa:
ALTER TABLE Szamla MODIFY Szamlaszam VARCHAR(26);
A fenti példa megváltoztatja egy adatbázis tábla egy oszlopának típusát.
DROP
szerkesztésAdatbázis-objektum megszűntetése. Példa:
DROP INDEX Szamla_1;
A fenti példa megszűntet egy indexet.
COMMENT
szerkesztésMegjegyzést fűz egy adatbázis-objektumhoz. Példa:
COMMENT ON TABLE Szamla IS 'Ügyfelek bankszámlaszámai'; COMMENT ON COLUMN Szamla.Allapot IS 'Számla állapota: "N" - Normál, "D" - Törölve';
A fenti példa megjegyzéseket fűz egy táblához és annak egy mezőjéhez.
Adatkezelő utasítások
szerkesztésSELECT
szerkesztésAz SQL legnagyszerűbb, és legjobban használható utasítása, a lekérdezés. Ez az a nyelvi elem, amely inkább deklaratívnak tekinthető, mint procedurálisnak, hiszen a felhasználó (programozó) csak azt határozza meg, milyen eredményhalmazt szeretne, de a leválogatási algoritmus elkészítése az adatbázis-kezelő feladata.
A SELECT utasítás az adatok egy halmazát válogatja ki egy táblázatba a relációs adatbázisból, és teszi elérhetővé valamilyen technikával a felhasználó számára. Mivel elég nagy adatmennyiségekről lehet szó (szélsőséges esetben az egész adatbázisról), ezért a halmaz általában szekvenciálisan olvasható. Egy mutató (kurzor) mozgatható az eredmény halmazon előre vagy hátra, és kiolvasható, hogy milyen adatok vannak a mutató alatt. Ha a mutató az eredményhalmaz végére vagy elejére ért, azt különleges jelzéssel tudatja az adatbázis-kezelő (EOF - End of File - állomány vége, illetve BOF - Beginning of File, állomány eleje)
Példa:
SELECT COUNT(*), Tulajdonos FROM Szamla WHERE Allapot = 'N' GROUP BY Tulajdonos HAVING COUNT(*) > 1 ORDER BY Tulajdonos
A fenti példa kilistázza azokat a személyeket, akiknek egynél több aktív bankszámlája van. Az első oszlopban az aktív bankszámlák száma, a másodikban a tulajdonosok neve olvasható. A táblázat a tulajdonosok neve szerinti emelkedő sorrendben jelenik meg.
A SELECT utasítás több szakaszból állhat, amelyek közül majdnem mindegyik elhagyható, ha az szükséges. Az egyes szakaszok magyarázata:
SELECT
szerkesztésAz eredményhalmaz oszlopait kell itt felsorolni. Nagyon hasznos, hogy további SELECT-ek is lehetnek benne!
Példa:
SELECT Vevo.Nev, (SELECT SUM(Osszeg) FROM Rendeles WHERE VevoID = Vevo.ID) RendelesOsszeg
A fenti példa a vevő neve mellett megjeleníti az eddigi rendeléseinek összegét is.
FROM
szerkesztésMeghatározza, hogy mely adatbázis-táblákból szeretnénk összegyűjteni az adatokat.
Példa:
SELECT * FROM Beteg, Kezeles
A fenti példa az összes beteggel összepárosítja az összes kezelést (Descartes-szorzatot képez). Ennek persze nincs túl sok értelme, hiszen mi minden beteghez csak a hozzá tartozó kezelést szeretnénk látni. Ezt így fogalmazhatjuk meg:
SELECT * FROM Beteg KEY JOIN Kezeles
A fenti példa akkor működik, ha van definiált külső kulcs a Kezeles tábláról a Beteg táblára. Egyes SQL kiszolgálók (pld. Oracle) ezt a fajta összekapcsolást nem támogatják, hiába definiálunk külső kulcsot.
WHERE
szerkesztésSzűrési feltételeket fogalmaz meg, amelyek szűkítik az eredményhalmazt (a Descartes-szorzathoz képest). Példa:
SELECT * FROM Beteg, Kezeles WHERE Beteg.ID = Kezeles.BetegID AND Kezeles.Datum = CURRENT DATE
A fenti lekérdezés visszaadja, milyen kezeléseket végeztek ma, és melyik betegeken. A WHERE szakaszban a Boole-algebra kifejezései használhatóak, OR, AND és NOT operátorokkal.
GROUP BY
szerkesztésEgyes sorok összevonását, csoportosítását írja elő az eredménytáblában. Példa:
SELECT COUNT(*), Tulajdonos FROM Szamla WHERE Allapot = 'N' GROUP BY Tulajdonos
A fenti példa a Tulajdonos oszlop alapján csoportosítja a sorokat. A SELECT részben lévő COUNT(*) egy-egy csoport sorainak számát adja vissza, az összevonás előtt.
HAVING
szerkesztésA WHERE-hez hasonlóan itt is szűrést fogalmazhatunk meg, azonban itt a csoportosítás utáni eredményhalmazra. Példa:
SELECT COUNT(*), Tulajdonos FROM Szamla WHERE Allapot = 'N' GROUP BY Tulajdonos HAVING COUNT(*) > 1
Az előző példához képest itt annyi a módosulás, hogy csak azok a csoporok jelennek meg, amelyek egynél több sorból lettek összevonva.
ORDER BY
szerkesztésAz eredményhalmaz rendezését adja meg. Példa:
SELECT * FROM Beteg ORDER BY Szuletes DESC
A fenti példa a betegek listáját adja vissza, születési dátum szerint sorba rendezve, elöl a legfiatalabb beteggel.
Lekérdezési terv
szerkesztésAngolul query plan.
A kurzor létrehozásának technikája adja az SQL kiszolgálók igazi erejét. Nem mindegy ugyanis, hogy sikerül-e a táblákat megfelelő oszlopok (és indexek!) segítségével összekapcsolni, és ezekből kurzort készíteni, vagy pedig átmeneti táblát kell létrehozni az eredményeknek.
Az egyes relációs adatbázis-kezelők egymástól igen eltérő algoritmusokat használnak a lekérdezési tervek megalkotásához. Gyakori a szabály-alapú (rule-based), és a költség-alapú (cost-based) lekérdezési terv készítés. A költség-alapú lekérdezési tervhez ismerni kell az adatok statisztikai eloszlását: átlagát, szórását, stb. A szabály-alapú lekérdezéseknél elegendő csak a relációs adatbázis szerkezetének ismerete. A legtöbb relációs adatbázis-kezelő a kettő valamilyen kombinációjával dolgozik.
Sok gyártó SQL megvalósításában lehetséges a keresési stratégia befolyásolása, úgynevezett programozói lekérdezési tippek (query hints) segítségével. Azonban minél jobb egy adatbázis-kezelő, annál kevésbé szükséges ezek használata.
INSERT
szerkesztésAdatokat ad hozzá egy táblához. Példa:
INSERT INTO Szamla (Szamlaszam, Tulajdonos, Nyitas, Allapot) VALUES (123456, 'H. Kovács Géza', '1996.05.14.', 'N');
UPDATE
szerkesztésMódosítást hajt végre az adatokon. Példa:
UPDATE Szamla SET Allapot = 'D' WHERE Szamlaszam = 123456;
A fenti utasítás megváltoztatja az egyik számla állapotát.
DELETE
szerkesztésAdatokat töröl egy táblából. Példa:
DELETE FROM Beteg WHERE TAJ = '123 456 789';
Ez az utasítás egy beteg összes adatát törli a Beteg táblából.
Egyéb utasítások
szerkesztésAz SQL-t az idők során kiegészítették olyan tulajdonságokkal, hogy a programozók képesek legyenek benne bonyolult algoritmusokat is írni. Ez akkor válhat szükségessé, ha például komoly adatkezelési feladatokat szeretnénk az ügyfél-oldalról a kiszolgáló-oldalra áthelyezni, az ott elérhető sokkal nagyobb tejesítmény miatt. De az is lehet, hogy csak egyszerűsíteni akarjuk a programozást felhasználói függvények létrehozásával (például szükségünk lenne egy olyan függvényre, ami a TAJ számból kiszedi a szóközöket).
Az SQL nyelv részei a változókezelés, elágazások, ciklusok kezelése, kivételkezelés, stb.
A legnagyobb különbségek az SQL kiszolgálók között éppen ezeknél a nyelvi elemeknél adódik: ahány gyártó, annyiféle megvalósítás.
Az egyéb nyelvi elemek szemléltetésére álljon itt egy Sybase ASA SQL példa:
CREATE FUNCTION DigitsOnly(IN M_Nev VARCHAR(30)) RETURNS VARCHAR(30) BEGIN DECLARE M_Result VARCHAR(16); DECLARE i INTEGER; SET i = 1; SET M_Result = ; WHILE (i <= LENGTH(M_Nev)) LOOP ID SUBSTR(M_Nev, i, 1) BETWEEN '0' AND '9' THEN SET M_Result = M_Result + SUBSTR(M_Nev, i, 1) END IF; SET i = i + 1; END LOOP; IF m_Result = THEN RETURN(Null) ELSE RETURN(M_Result) END IF; END;
A fenti függvény a bemenetére küldött szövegből csak a számjegyeket hagyja meg.
Jelentős különbségek az SQL megvalósítások között
szerkesztésAdattípusok
szerkesztés- Az Oracle rendszereiben nincs NUMERIC, helyette a NUMBER-t kell használni
- Az Oracle nem támogatja a VARCHAR-t, helyette a VARCHAR2-t javasolja
- Az Oracle nem támogatja a LONG VARCHAR-t, helyette a CLOB-ot javasolja
- Oracle-ben a DATE dátumot és időt is tartalmazhat, más rendszerekben ez csak dátum lehet
- Egyes megvalósításokban (pld. PostgresSQL) létezik általános típusú adat is, amelyben akármit és akármekkora terjedelemben tárolhatunk
- Némelyik rendszerben létezik a SMALLINT vagy az INTEGER típus is, mint szabványon kívüli elemek
- Van olyan rendszer, amiben a BOOL típust is megvalósították
Összekapcsolás
szerkesztésAz SQL kiszolgálók egy része támogatja a SELECT-FROM szakaszba írt összekapcsolási utasításokat, mások csak a SELECT-WHERE szakaszban fogadják el:
Összekapcsolás a SELECT-FROM-ban:
SELECT * FROM Beteg KEY JOIN Lelet
Összekapcsolás a WHERE-ben:
SELECT * FROM Beteg, Lelet WHERE Beteg.ID = Lelet.BetegID
Keresés
szerkesztésBizonyos SQL kiszolgálók gyors keresésnél csak a teljesen pontosan beírt keresőkérdésre találják meg a választ. Gondot kell fordítanunk a kis- és nagybetűkre, valamint az ékezetek helyes használatára (Oracle, Firebird, PostgresSQL).
Más SQL kiszolgálók képesek figyelmen kívül hagyni az ékezeteket és egyenrangúnak tekintik a kis- és nagybetűket a keresés során, ha ezt kérjük (Sybase ASE, Sybase ASA).