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és]Az 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és]A 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és]CREATE
[szerkesztés]Adatbá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és]Adatbá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és]Adatbázis-objektum megszűntetése. Példa:
DROP INDEX Szamla_1;
A fenti példa megszűntet egy indexet.
COMMENT
[szerkesztés]Megjegyzé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és]SELECT
[szerkesztés]Az 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és]Az 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és]Meghatá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és]Szű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és]Egyes 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és]A 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és]Az 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és]Angolul 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és]Adatokat 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és]Mó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és]Adatokat 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és]Az 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és]Adattí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és]Az 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és]Bizonyos 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).