SQL
SQL | |
Paradigma | deklaratív, procedurális |
Jellemző kiterjesztés | sql |
Megjelent | 1974 |
Tervező |
|
Fejlesztő |
|
Utolsó kiadás | SQL:2017 (2017) |
Hatással volt rá |
|
Weboldal |
Az SQL, azaz Structured Query Language (strukturált lekérdezőnyelv) relációsadatbázis-kezelők lekérdezési nyelve.
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 (SEQUEL) volt az elnevezés, és ezt rövidítették le.
A relációsadatbá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 inkompatibilitás, emiatt számos SQL nyelvjárásról beszélhetünk.
Jellegét tekintve ez a szakterület-specifikus 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 SQL leírását az ISO 9075 szabvány rögzíti.[1] Az első változatot SQL86 néven is szokták emlegetni.
Az SQL-t folyamatosan továbbfejlesztették, és napjainkig nyolc jelentős kiadást különböztetünk meg:
- SQL86
- SQL89
- SQL92
- SQL99 (v. más néven: SQL3)
- SQL:2006
- SQL:2008
- SQL:2011
- SQL:2017
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]Az SQL nyelvi elemeket 4 részre, adatdefiníciós (Data Definition Language, DDL), adatkezelési (Data Manipulation Language, DML), lekérdező (QUERY (Language - QL)) és adatvezérlő (Data Control Language, DCL) részekre lehet bontani.
A nyelvben az utasításokat a pontosvessző választja el egymástól.
Adatdefiníciós utasítások (Data Definition Language - DDL)
[szerkesztés]Azt a nyelvet melynek segítségével az adatbázis adminisztrátorok az új adatbázisok sémáját definiálják adatdefiníciós nyelveknek (DDL = Data Definition Language) nevezzük.
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
ALTER COLUMN Szamlaszam VARCHAR(26);
A fenti példa megváltoztatja egy adatbázis tábla egy oszlopának típusát.
DROP
[szerkesztés]Egy adatbázisbeli objektum megszüntetése. Példa:
DROP INDEX Szamla_1;
A fenti példa megszüntet egy indexet.
DROP TABLE egy_tabla;
Ez pedig egy adattáblát szüntet meg.
TRUNCATE
[szerkesztés]A truncate parancs egy tábla tartalmát törli (de a táblát magát nem).
TRUNCATE TABLE egy_tabla;
A DDL (Data Definition) és DML (Data Manipulation) között jelentős különbség nem abban áll, hogy változtat-e az adatbázis tartalmán (hiszen például a szó szoros értelmében adat "törlés" történik drop, truncate és delete esetén is). A különbség a tranzakcióbiztosságban vehető észre: a ddl utasítások nem tranzakcióbiztosak, azaz azonnal végrehajtásra kerülnek, míg a dml utasítások (delete, insert, update) csak COMMIT parancs után válnak véglegessé. Ez a gyakorlatban:
- ha például update történik egy táblán, azt a másik felhasználó csak akkor láthatja ha commit is történik
- ha drop paranccsal megszüntetünk egy objektumot, akkor automatikusan törlődik
- dml parancsok commitálása (véglegesítése) előtt egy ROLLBACK paranccsal visszavonhatóak
- a truncate parancs ennek megfelelően ddl parancsnak minősíthető
Adatlekérdező utasítások (Data Query Language - DQL)
[szerkesztés]A lekérdező nyelv egyetlen utasításból áll, mely számos alparancsot tartalmazhat, és a lekérdező utasítások többszörös mélységben egymásba ágyazhatók. Célja, hogy egy vagy több adathalmazból (reláció) egy adathalmazt állítson elő. A bemeneti adatokon, a relációs algebra műveletei hajthatóak végre, aminek következményeként egy eredmény táblát kap a felhasználó. Végrehajtási sorrendjük a következő: FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY.[2]
SELECT
[szerkesztés]Az SQL talán leggyakrabban használt utasítása a lekérdezés. Ez a nyelvi elem inkább deklaratívnak[3] tekinthető, mint procedurálisnak, hiszen a felhasználó (programozó) csak az eredményhalmaz mezőit (oszlopait) és a halmaz felépítésének feltételeit határozza meg, 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 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.
Összetettebb példa:
SELECT munka_szám FROM munka
WHERE óraszám*óradíj = (
SELECT max(óraszám*óradíj) FROM munka
);
A lekérdezés megkeresi a legnagyobb árbevételű munkáinkat – akkor használható jól, ha több is van belőle.
FROM
[szerkesztés]Meghatározza, hogy mely adatbázis-táblákból szeretnénk összegyűjteni az adatokat.
Példa a hagyományos (limitált képességű, néha problémás) szintaxissal:
SELECT *
FROM Beteg, Kezeles
WHERE Kezeles.Beteg_ID = Beteg.Beteg_ID
vagy az újabb módszer szerint:
SELECT *
FROM Beteg
INNER JOIN Kezeles ON Kezeles.Beteg_ID = Beteg.Beteg_ID
az összes beteg-kezelés párost adja. Amelyik betegnek nem volt kezelése, azt nem írja ki, amelyiknek több volt, azt annyiszor, ahány kezelésen átesett.
LEFT esetén: az első tábla adatai akkor is szerepelnek, ha nincs illeszkedő adat a másodikban (azaz a fenti példában megmutatja azokat a betegeket is, akinek soha nem volt kezelése)
RIGHT esetén: a második tábla adatai akkor is szerepelnek, ha nincs illeszkedő adat az elsőben (itt ugyanazt az eredményt adja, mint INNER esetén, ha minden kezeléshez tartozik beteg)
FULL OUTER: mindkét táblából megmutatja az összes sort (itt megegyezik a LEFT JOIN eredményével, ha minden kezeléshez tartozik beteg
CROSS: a táblák Descartes szorzatát képezi, azaz az összes lehetséges kombinációt megmutatja. Ekkor a modern szintaxis szerint az ON részre nincs szükség, a régi szerint pedig a WHERE rész nem kell. A gyakorlatban erre a változatra nagyon ritkán van szükség, itt sem adna értelmes adatokat.
A FROM részben a beágyazott lekérdezések (nested query) használatát nagy táblák esetében érdemes elkerülni, mert feleslegesen terhelheti a szervert, illetve megnyújthatja a lekérdezés futás idejét. Egyik lehetséges kerülő megoldás az ideiglenes táblák használata, melyet az eredeti lekérdezésünk elé írt WITH SubQueryTableName AS (SELECT ... FROM ... WHERE ...) szintaxissal valósítható meg.
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ók, 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 csoportok 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.
CASE
[szerkesztés] CASE WHEN logikai vizsgálat THEN kifejezés ha igaz .. ELSE kifejezés ha az előzőekre nem illeszkedik END
A logikai vizsgálat eredményétől függően vezérelhetjük, hogy mit szeretnénk az adott oszlopban látni. Példa:
select app_id,budget_info_type,amount
from acq_budget_info
A lekérdezés eredménye:
APP_ID BUDGET_INFO_TYPE AMOUNT ---------- ------------------------ ----------- 0001 net_income 110000 0001 bonus 7500 0001 gross_income 1000 0002 gross_income 2000 0002 net_income 120000 0002 bonus 8500 0003 gross_income 3000 0003 bonus 9500 0003 net_income 130000
Az előző lekérdezés transzponáltja:
select APP_ID, max(net_income) as net_inc, max(gross_income) as gross_inc, max(bonus) as bonus_inc
from (
select APP_ID,
case when BUDGET_INFO_TYPE='net_income' then amount else null end as net_income,
case when BUDGET_INFO_TYPE='gross_income' then amount else null end as gross_income,
case when BUDGET_INFO_TYPE='bonus' then amount else null end as bonus
from acq_budget_info) xx
group by APP_ID
APP_ID net_inc gross_inc bonus_inc ---------- ----------- ------------- ------------- 0001 110000 1000 7500 0002 120000 2000 8500 0003 130000 3000 9500
Megjegyzések:
- az oszlopoknál megadott alias elnevezéseknél az 'as' elhagyható
- a belső select-tet tartalmazó táblára illesztett alias ("xx") elhagyható Oracle, SQLite esetén de szükséges MySQL, PostrgreSQL és MS SQL Server esetén
Adatmanipulációs nyelv (Data Manipulation Language - DML)
[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ósadatbázis-kezelők egymástól igen eltérő algoritmusokat használnak a lekérdezési tervek megalkotásához. Gyakori a szabályalapú (rule-based), és a költségalapú (cost-based) lekérdezésiterv-készítés. A költségalapú lekérdezési tervhez ismerni kell az adatok statisztikai eloszlását: átlagát, szórását stb. A szabályalapú lekérdezéseknél elegendő csak a relációs adatbázis szerkezetének ismerete. A legtöbb relációsadatbá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 annak a betegnek, akinek a tajszáma:123 456 789, törli az összes adatát a Beteg táblából.
Adatelérést Vezérlő Nyelv (Data Control Language - DCL)
[szerkesztés]A jogosultságok adása és a vezérlők működésének szabályozása. Ide szokás sorolni: GRANT, REVOKE, COMMIT, ROLLBACK, SAVEPOINT (ez utóbbi nem minden sql-ben szerepel, pl oracle verzióban nem)
GRANT
[szerkesztés]Ezzel tudunk adni jogosultságot egy tábla eléréséhez, adott parancs létrehozásához. Két fajtája van:
- adott objektumra vonatkozó jogosultság: table privilege - például: egy adott táblán tudjon lekérdezni, beszúrni vagy törölni, ekkor természetesen meg kell adni, hogy melyik objektumról van szó
- egyfajta parancs létrehozására vonatkozó jogosultság: system privilege - például tudjon létrehozni vagy törölni táblát
Példák:
grant select on egy_tabla to user1;
Ezzel a user1 felhasználó tud select-tet végrehajtani az egy_tabla-n.
grant create table to user1;
Ezzel a user1 felhasználó tud táblát létrehozni.
REVOKE
[szerkesztés]Ezzel tudunk meglévő jogosultságot visszavonni.
revoke create table from user1;
revoke select on egy_tabla from user1;
Egyéb utasítások
[szerkesztés]JOIN
[szerkesztés]Az összekapcsolás lényege, hogy két vagy több táblában tárolt adatokat tudunk lekérdezni az alapján, hogy hol egyezik a megadott mezőérték.
Példatáblák: az alábbi két táblán (gepjarmu és javitasok) összekapcsolások segítségével tudjuk meghatározni, hogy pl milyen rendszámú autón milyen javítás szükséges vagy adott javításhoz melyik gépjárműhöz tartozik.
SELECT * FROM gepjarmu;
car_azonosito rendszam
--------------- ----------
1001 ZQL-556
1002 WPT-444
1003 ZRM-555
SELECT * FROM javitasok;
car_ID alkatresz
------------- ------------
1001 váltó
1001 kerék
1002 kerék
1004 futómű
Általában a két táblában lévő azonosító oszlop elnevezése megegyezik (pl. car_azonosito lenne a javitasok táblában is), de ez nem szükséges, ezért szerepel kétfajta elnevezés a két táblában.
CROSS JOIN
[szerkesztés]Cartesian-join, Descartes-szorzat
A feltétel nélküli összekapcsolás. Ez az összekapcsolás a két tábla minden sorát összekapcsolja. Az inner join ennek részhalmaza (az a where feltétel, amikor egyezik a két táblában az azonositó)
select * from gepjarmu
cross join javitasok
car_azonosito rendszam car_ID alkatresz
--------------- --------------- --------------- ---------------
1001 ZQL-556 1001 váltó
1001 ZQL-556 1002 kerék
1001 ZQL-556 1002 váltó
1001 ZQL-556 1004 futómű
1002 WPD-444 1001 váltó
1002 WPD-444 1002 kerék
1002 WPD-444 1002 váltó
1002 WPD-444 1004 futómű
1003 ZRM-555 1001 váltó
1003 ZRM-555 1002 kerék
1003 ZRM-555 1002 váltó
1003 ZRM-555 1004 futómű
Amennyiben feltétel nélkül select-tet adunk meg két táblával, akkor a cross join-nak megfelelő eredményt kapjuk:
select * from gepjarmu, javitasok
A cartesian join sorainak száma a két tábla sorainak számának szorzata. A példában: 3 • 4 = 12
INNER JOIN
[szerkesztés]Belső összekapcsolás, metszet
A két tábla metszete, azaz azok a sorok, amelyek mindkét táblában megtalálhatóak.
select * from gepjarmu, javitasok
where gepjarmu.car_azonosito = javitasok.car_ID
car_azonosito rendszam car_ID alkatresz
--------------- --------------- --------------- ---------------
1001 ZQL-556 1001 váltó
1002 WPD-444 1002 kerék
1002 WPD-444 1002 váltó
Ebben a select-ben csak azok a sorok jelennek meg, amelyek mindkét táblában megtalálhatóak (1001 és 1002 azonosítójú autók) és annyiszor ahány sorban megjelenik az azonosító (az 1002-es azonosítójú gépjármű kétszer, mert a javitasok táblában kétszer szerepel.) A where feltételben megadott inner join jól mutatja, hogy az inner join a cartesian join (minden-mindennel) azon részhalmaza, ahol egyezik az azonosító. Az inner join másfajta felírása (eredménye ugyanaz mint a where feltételben megadott összekapcsolás)
select * from gepjarmu
inner join javitasok
on gepjarmu.car_azonosito = javitasok.car_ID
Az „inner” szó elhagyható, az önállóan feltüntetett „join” is ugyanúgy az inner join-t adja.
LEFT JOIN
[szerkesztés]Baloldali kapcsolás. A kapcsolás alapját (értelmezési tartományát, gepjarmu tábla) adó tábla összes sorához történik hozzárendelés.
select * from gepjarmu
left join javitasok
on gepjarmu.car_azonosito = javitasok.car_ID;
car_azonosito rendszam car_ID alkatresz
--------------- --------------- --------------- ---------------
1001 ZQL-556 1001 váltó
1002 WPD-444 1002 kerék
1002 WPD-444 1002 váltó
1003 ZRM-555 (null) (null)
- ha szerepel a másik táblában érték akkor azt rendeli hozzá (pl. 1001-es gépjárműhöz ’váltó’)
- ha többször szerepel a másik táblában érték, akkor annyiszor kerül feltüntetésre, ahány sorban megtalálható a másik táblában (pl. az 1002-es gépjármű kétszer szerepel, mert két sorban is megjelenik a javitasok táblában: ’kerék’ és ’váltó’)
- ha nem található meg a második táblában akkor NULL érték kerül hozzárendelésre (pl az 1003-as gépjármű nincs benne a javitasok táblában)
Használatos a left join helyett a left outer join parancs, amely tartalmilag megegyezik.
RIGHT JOIN
[szerkesztés]Jobboldali kapcsolás. A kapcsolt (második, javitasok tábla) minden eleméhez elvégzi a hozzákapcsolást.
select * from gepjarmu
right join javitasok
on gepjarmu.car_azonosito = javitasok.car_ID;
car_azonosito rendszam car_ID alkatresz
--------------- --------------- --------------- ---------------
1001 ZQL-556 1001 váltó
1002 WPD-444 1002 kerék
1002 WPD-444 1002 váltó
(null) (null) 1004 futómű
- ha szerepel az első táblában érték, akkor azt rendeli hozzá (pl. 1001-es car_ID gépjárműhöz található rendszám)
- ha többször szerepel a táblában akkor annyiszor kerül felsorolásra, ahány ilyen sor van (pl. az 1002-es gépjármű kétszer szerepel, ezért két sorban kapjuk eredményül)
- ha a második táblában szerepel, de az elsőben nem, akkor is megjelenik a lekérdezésben, de NULL értékkel (például az 1004-es gépjármű csak a javitasok táblában található, a gepjarmu táblában nem)
Használatos a right join helyett a right outer join parancs, amely tartalmilag megegyezik.
FULL JOIN
[szerkesztés]Mindkét oldalról elvégzi az összekapcsolást, azaz az előző három join uniója:
- inner join
- right join
- left join
select * from gepjarmu
full join javitasok
on gepjarmu.car_azonosito = javitasok.car_ID;
car_azonosito rendszam car_ID alkatresz
--------------- --------------- --------------- ---------------
1001 ZQL-556 1001 váltó
1002 WPD-444 1002 kerék
1002 WPD-444 1002 váltó
1003 ZRM-555 (null) (null)
(null) (null) 1004 futómű
Tehát a left join, right join és inner join megfogalmazható úgy is, hogy ezek a full join részhalmazai. Az inner join a full join olyan részhalmaza, amely sorban nem szerepelnek (null) értékek. Mivel a full join a három join uniója, ezért helyettesíthető az alábbi paranccsal:
select * from gepjarmu
inner join javitasok
on gepjarmu.car_azonosito = javitasok.car_ID
union
select * from gepjarmu
left join javitasok
on gepjarmu.car_azonosito = javitasok.car_ID
union
select * from gepjarmu
right join javitasok
on gepjarmu.car_azonosito = javitasok.car_ID
A full join szerepel az Oracle, ProstgreSQL és MS SQL Server verziókban, de nem szerepel a MySQL, SQLite típusokban – ez utóbbi esetekben az előző union paranccsal tudjuk létrehozni.
A full join és cartesian join kapcsolata: két tábla cartesian join (minden adat mindegyikkel kapcsolva) és full join halmazainak metszete a két tábla inner join-ja.
Használatos a full join helyett a full outer join parancs, amely tartalmilag megegyezik.
SELF JOIN és tábla alias
[szerkesztés]Érdemes használni a tábla nevekre a lekérdezésekben aliast, mert megkönnyíti a hivatkozást:
select * from gepjarmu a, javitasok b
where a.car_azonosito = b.car_ID
Szükséges lehet önmagával kapcsolni a táblát (self-join). Ebben az esetben a két táblát alias-szal tudjuk megkülönböztetni. A következő példában szeretnénk kigyűjteni a dolgozo táblából minden dolgozóhoz a nálánál kevesebbet keresőket.
select * from dolgozo
name sal
---------- ----------
Nagy 7500
Balogh 7600
Kovács 7700
Szabó 7800
select * from dolgozo x, dolgozo y
where x.sal < y.sal
name sal name sal
---------- ---------- ---------- ----------
Nagy 7500 Balogh 7600
Nagy 7500 Kovács 7700
Balogh 7600 Kovács 7700
Nagy 7500 Szabó 7800
Balogh 7600 Szabó 7800
Kovács 7700 Szabó 7800
Változók, elágazások, ciklusok
[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éloldalról a kiszolgálóoldalra áthelyezni, az ott elérhető sokkal nagyobb teljesí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 tajszá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
IF 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 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. PostgreSQL) létezik általános típusú adat is (bytea), 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
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, PostgreSQL).
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).
FROM nélküli SELECT
[szerkesztés]FROM nélküli SELECT utasításra példa:
SELECT SYSDATE
A fenti példa egyes SQL kiszolgálók esetében nem működik, mivel a FROM náluk kötelező nyelvi elem.
Ezért például az Oracle minden adatbázisában szerepelteti a DUAL táblát, amelynek egyetlen rekordja van. Így Oracle SQL-ben ezt kell írnunk:
SELECT SYSDATE FROM DUAL
Természetesen itt a DUAL tábla valódi tartalma lényegtelen.
Bármely adatbankban, ha számolási eredményekre kíváncsi a felhasználó, lehetséges egy dummy (vagy tetszőleges nevű) üres tábla létrehozása, majd ennek felhasználásaval aritmetikai műveletek végezhetők el. Példa:
create table dummy (teszt numeric)
insert into dummy values(0)
select (12 88)/3 from dummy
Jegyzetek
[szerkesztés]- ↑ ISO/IEC 9075-1:2011 - Information technology -- Database languages -- SQL -- Part 1: Framework (SQL/Framework). ISO. [2016. május 13-i dátummal az eredetiből archiválva]. (Hozzáférés: 2017. január 17.)
- ↑ Az SQL nyelv alapjai, 2009. április 9. [2012. január 14-i dátummal az eredetiből archiválva]. (Hozzáférés: 2012. június 14.)
- ↑ Archivált másolat. [2013. április 25-i dátummal az eredetiből archiválva]. (Hozzáférés: 2012. március 2.)