Grafikus C# – Windows Forms tanfolyam › 3.5 lecke Windows Forms · 3.5 lecke · lekérdezések Az adatbázisok igazi ereje a lekérdezésekben van: nem az egész táblát kell megnézned, hanem csak azt, amire szükséged van, a kívánt sorrendben. Ebben a leckében az SQL SELECT, WHERE, ORDER BY és rekordok rendezése
WHERE, LIKE, BETWEEN, ORDER BY, DISTINCT és LIMIT kulcsszavait tanulod meg, majd egy dolgozói keresőt építesz, amelynek szűrői és rendezése együtt működik.
A lecke végére
- a
WHEREfeltételeit (=,<>,<,>,BETWEEN,IN,LIKE,IS NULL) használod, és összekapcsolodAND,ORés zárójelek segítségével; - az
ORDER BYkulcsszóval több szempont szerint rendezel; - a
DISTINCTés aLIMIThasználatával egyedi értékeket és „első néhány” sort kérdezel le; - választható szűrőket építesz egyetlen paraméteres lekérdezésbe;
- érted, miért nem paraméterezhető az
ORDER BY, és hogyan rendezel biztonságosan; - ismered az SQLite
LIKEékezetes betűkkel kapcsolatos korlátját.
Mielőtt elkezded
Ehhez a leckéhez kell a 3.4 lecke projektje (DB.cs, kapcsolat, DataTable és DataGridView), és a belepes.db adatbázisban az adatok tábla a 3.1 lecke mini projektjéből (id, vnev, knev, fizetes, cim).
WHERE: a sorok szűrése
A SELECT alapból az összes sort adja. A WHERE után megadott feltétel csak azokat hagyja meg, amelyekre igaz. A leggyakoribb feltételek:
| Feltétel | Jelentése | Példa |
|---|---|---|
=, <> | egyenlő, nem egyenlő | WHERE cim = 'Győr' |
<, <=, >, >= | összehasonlítás | WHERE fizetes >= 400000 |
BETWEEN a AND b | két érték között (a határokat is beleértve) | WHERE fizetes BETWEEN 300000 AND 450000 |
IN (…) | a felsorolt értékek valamelyike | WHERE cim IN ('Győr', 'Pécs') |
LIKE | mintaillesztés (%: bármennyi karakter, _: pontosan egy) | WHERE vnev LIKE 'K%' |
IS NULL | nincs érték (üres) | WHERE cim IS NULL |
AND, OR, NOT | feltételek összekapcsolása, tagadás | WHERE cim = 'Győr' AND fizetes > 300000 |
Az AND erősebb, mint az OR
Ha AND és OR együtt szerepel, előbb az AND értékelődik ki. A WHERE cim = 'Győr' OR cim = 'Pécs' AND fizetes > 400000 azt jelenti: Győrben bárki, vagy Pécsett aki 400 000 fölött keres. Ha mást szeretnél, használj zárójelet: WHERE (cim = 'Győr' OR cim = 'Pécs') AND fizetes > 400000.
Jósolj!
A táblában az egyik dolgozónak nincs megadva a címe (NULL). Szerepel-e az eredményben a SELECT * FROM adatok WHERE cim <> 'Győr' lekérdezésnél?
Jóslat ellenőrzése
Nem. A NULL az SQL-ben „ismeretlen érték”, és minden hagyományos összehasonlítás vele (=, <>, >) eredménye sem igaz, sem hamis, ezért a sor kimarad. Ha a címnélküli dolgozót is látni szeretnéd, ezt külön kell kérni: WHERE cim <> 'Győr' OR cim IS NULL. A hiányzó értéket mindig az IS NULL, illetve az IS NOT NULL vizsgálja, a = NULL nem működik.
ORDER BY, DISTINCT és LIMIT
A sorok sorrendjét az ORDER BY adja meg. Az ASC növekvő (ez az alapértelmezett), a DESC csökkenő sorrend. Több szempontot vesszővel sorolhatsz fel: az első szerint rendez, az azonosak között a második dönt.
-- név szerint, ábécében
SELECT * FROM adatok ORDER BY vnev, knev;
-- legjobban fizetettek elöl
SELECT vnev, knev, fizetes FROM adatok ORDER BY fizetes DESC;
-- városonként, azon belül fizetés szerint csökkenően
SELECT cim, vnev, fizetes FROM adatok ORDER BY cim, fizetes DESC;
-- melyik városokban laknak dolgozóink? (minden város csak egyszer)
SELECT DISTINCT cim FROM adatok ORDER BY cim;
-- a három legjobban fizetett dolgozó
SELECT vnev, knev, fizetes FROM adatok ORDER BY fizetes DESC LIMIT 3;ORDER BY után áll, így „a legjobb n” lekérdezhető.Jósolj!
Mit ad a SELECT vnev FROM adatok LIMIT 3, ha nincs ORDER BY? Ugyanazt kapod-e, ha a tábla sorait másik sorrendben vitték fel?
Jóslat ellenőrzése
Három sort ad, de nincs garantált sorrend: az adatbázis tetszőleges három sort adhat (jellemzően a felvétel sorrendjében, de erre nem szabad építeni). Ha más sorrendben vitték fel a sorokat, más három sort kaphatsz. A LIMIT-et ezért mindig ORDER BY-jal együtt használd, különben nem tudod, melyik n sort kapod.
Gyakorlóadatok és kipróbálás a DB Browserben
Hogy a szűrőknek legyen mit szűrniük, bővítsd az adatok táblát további sorokkal (az Execute SQL lapon, majd Ctrl+S). Az utolsó sor szándékosan hiányos: nincs címe.
INSERT INTO adatok (vnev, knev, fizetes, cim) VALUES ('Kiss', 'Márta', 380000, 'Győr');
INSERT INTO adatok (vnev, knev, fizetes, cim) VALUES ('Varga', 'Dávid', 450000, 'Pécs');
INSERT INTO adatok (vnev, knev, fizetes, cim) VALUES ('Kelemen', 'Zita', 330000, 'Veszprém');
INSERT INTO adatok (vnev, knev, fizetes, cim) VALUES ('Árpád', 'Lili', 410000, 'Győr');
INSERT INTO adatok (vnev, knev, fizetes) VALUES ('Molnár', 'Gábor', 360000);Próbáld ki a leckében látott lekérdezéseket, és figyeld meg az eredményt:
| Lekérdezés | Mit várj? |
|---|---|
SELECT * FROM adatok WHERE cim = 'Győr' | Három sor: Szabó Kata, Kiss Márta, Árpád Lili. |
SELECT * FROM adatok WHERE fizetes BETWEEN 300000 AND 400000 | A határok is beleszámítanak. |
SELECT * FROM adatok WHERE vnev LIKE 'K%' | Kovács, Kiss, Kelemen. |
SELECT * FROM adatok WHERE cim IS NULL | Molnár Gábor. |
SELECT * FROM adatok WHERE cim <> 'Győr' | Molnár Gábor nem szerepel (NULL). |
A LIKE és az ékezetes betűk
Az SQLite LIKE operátora alapból a kis- és nagybetűt csak az angol (ASCII) betűknél tekinti azonosnak: a 'k%' megtalálja a Kovács nevet, de a 'á%' nem találja meg az Árpád nevet, mert az á és az Á ékezetes betű különbözőnek számít. Magyar szövegeknél ezért a kisbetű–nagybetű keresés a LIKE-kal nem teljes értékű. A kereső készítésekor gondolj erre, és tesztelj ékezetes nevekkel is.
Mit tegyél ide: a DB Browser Execute SQL lapja a WHERE vnev LIKE 'K%' lekérdezéssel és az eredményt mutató táblával.Javasolt fájlnév: winforms-3-5-like.webp · Alt szöveg: LIKE lekérdezés eredménye a DB Browserben
A dolgozói kereső: választható szűrők egy lekérdezésben
Építsünk ablakos keresőt. Az ablakon (új projekt a 3.2–3.4 szerint, a belepes.db-vel és a DB.cs osztállyal) ezek lesznek:
DropDownList). Az első elem: (összes).Maximum: 1000000, Increment: 10000).DropDownList).A legfontosabb ötlet: nem írunk különböző lekérdezést minden szűrőkombinációhoz. Egyetlen lekérdezés minden szűrőt tartalmaz, és az üres szűrő mindent átenged:
public static DataTable Dolgozok(string nevresz, int minFizetes, string varos, int rendezes)
{
// az ORDER BY a program rögzített szövegeiből áll össze, soha nem a felhasználó szövegéből
string sorrend = "vnev, knev";
if (rendezes == 1)
{
sorrend = "fizetes DESC";
}
else if (rendezes == 2)
{
sorrend = "fizetes ASC";
}
else if (rendezes == 3)
{
sorrend = "cim, vnev";
}
string sql = "SELECT id, vnev, knev, fizetes, cim FROM adatok "
+ "WHERE (vnev LIKE @minta OR knev LIKE @minta) "
+ "AND fizetes >= @min "
+ "AND (@varos = '' OR cim = @varos) "
+ "ORDER BY " + sorrend;
DataTable tabla = new DataTable();
using (SQLiteConnection kapcsolat = UjKapcsolat())
{
kapcsolat.Open();
using (SQLiteCommand parancs = new SQLiteCommand(sql, kapcsolat))
{
parancs.Parameters.AddWithValue("@minta", "%" + nevresz + "%");
parancs.Parameters.AddWithValue("@min", minFizetes);
parancs.Parameters.AddWithValue("@varos", varos);
using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(parancs))
{
adapter.Fill(tabla);
}
}
}
return tabla;
}
public static DataTable Varosok()
{
DataTable tabla = new DataTable();
using (SQLiteConnection kapcsolat = UjKapcsolat())
{
kapcsolat.Open();
using (SQLiteDataAdapter adapter = new SQLiteDataAdapter("SELECT DISTINCT cim FROM adatok WHERE cim IS NOT NULL ORDER BY cim", kapcsolat))
{
adapter.Fill(tabla);
}
}
return tabla;
}%%, amely minden szöveget elfogad. A zárójel azért kell, hogy az OR ne keveredjen a többi feltétellel.NULL fizetésű dolgozó kimarad: lásd a gyakorlótárat.)% jeleket a C# kód fűzi a beírt szöveg köré, és az egész minta megy paraméterként. A felhasználó szövege itt sem kerül az SQL szövegébe (3.3 lecke).Varosok() minden várost egyszer ad vissza, a NULL címet kihagyja.Miért nem paraméter az ORDER BY? A felület bekötése
Az oszlopnév vagy a rendezés iránya nem adható át paraméterként. A paraméter mindig érték, nem a lekérdezés szerkezetének része: ha az ORDER BY @oszlop parancsba a "fizetes" szöveget adnád, az adatbázis egy állandó szöveg szerint rendezne, vagyis valójában nem rendezne semmit. Ezért építünk a rendezésnél a program rögzített szövegeiből választva (a DB.Dolgozok if–else lánca), és a felhasználó csak egy sorszámot (SelectedIndex) ad meg. Így sosem kerülhet idegen szöveg az SQL szerkezetébe.
Szabály az SQL-ben összefűzhető részekre
Összefűzni csak olyan szöveget szabad az SQL-be, amelyet a program rögzített listájából választottál ki (oszlopnevek, rendezési irány). A felhasználó beírt szövegét mindig paraméterként add át.
Az ablak kódja minden szűrő változásakor újra lekérdez. Mivel az ablak betöltésekor a listák feltöltése is kiváltja a változás eseményeit, egy jelzőváltozó (mező) védi a korai lefutást (mint a 2.11 leckében):
private bool betoltve = false;
private void Form1_Load(object sender, EventArgs e)
{
cmbRendezes.Items.Add("Név szerint");
cmbRendezes.Items.Add("Fizetés szerint, csökkenő");
cmbRendezes.Items.Add("Fizetés szerint, növekvő");
cmbRendezes.Items.Add("Város szerint");
cmbRendezes.SelectedIndex = 0;
try
{
cmbVaros.Items.Add("(összes)");
foreach (DataRow sor in DB.Varosok().Rows)
{
cmbVaros.Items.Add(sor["cim"].ToString());
}
cmbVaros.SelectedIndex = 0;
}
catch (Exception ex)
{
MessageBox.Show("Nem sikerült betölteni a városokat: " + ex.Message);
}
betoltve = true;
Frissit();
}
private void Frissit()
{
if (!betoltve)
{
return;
}
try
{
string varos = cmbVaros.SelectedIndex <= 0 ? "" : cmbVaros.SelectedItem.ToString();
DataTable tabla = DB.Dolgozok(txtKereses.Text.Trim(), (int)nudMinFizetes.Value, varos, cmbRendezes.SelectedIndex);
dgvDolgozok.DataSource = tabla;
dgvDolgozok.Columns["vnev"].HeaderText = "Vezetéknév";
dgvDolgozok.Columns["knev"].HeaderText = "Keresztnév";
dgvDolgozok.Columns["fizetes"].HeaderText = "Fizetés (Ft)";
dgvDolgozok.Columns["cim"].HeaderText = "Város";
lblDarab.Text = tabla.Rows.Count + " találat";
}
catch (Exception ex)
{
MessageBox.Show("Adatbázis-hiba: " + ex.Message);
}
}
// ugyanezt hívja: txtKereses.TextChanged, cmbVaros.SelectedIndexChanged,
// nudMinFizetes.ValueChanged, cmbRendezes.SelectedIndexChanged
private void SzuroValtozott(object sender, EventArgs e)
{
Frissit();
}Frissit() kilép. Így a lista feltöltésekor kiváltott események még nem futtatnak lekérdezést félkész állapotban.-1) vagy az első, (összes) elem, a város szűrője kikapcsol.DataSource után újra be kell állítani.Jósolj!
A név mezőbe az a betűt írod, a város (összes), a minimális fizetés 0, a rendezés „Fizetés szerint, csökkenő”. Milyen sorrendben jönnek a találatok? Szerepel-e a címnélküli Molnár Gábor?
Jóslat ellenőrzése
A találatok a fizetés szerint csökkenően jönnek, legnagyobbal kezdve. Molnár Gábor szerepel, mert a város szűrője ((összes)) ilyenkor üres szöveget ad, és az (@varos = '' OR ...) feltétel első fele igaz, így a NULL cím nem akadályozza. A fizetes >= 0 igaz a 360 000 Ft-ra is. A név találat: a „Molnár Gábor” nevekben szerepel az a betű. (A NULL fizetésű sor viszont kimaradna, mert a fizetes >= 0 vele nem igaz.)
Mit tegyél ide: a futó dolgozói kereső: a szűrők a tetején, a találatok táblázata a darabszámmal („5 találat”).Javasolt fájlnév: winforms-3-5-kereso.webp · Alt szöveg: A dolgozói kereső szűrőkkel és találati táblázattal
Hibakeresés: te vagy a hibadetektív
Mi a baj, és hogyan javítod?
Gondold végig az okot, és csak utána nyisd le a megoldást.
1. A rendezés nem működik
string sql = "SELECT * FROM adatok ORDER BY @oszlop";
parancs.Parameters.AddWithValue("@oszlop", "fizetes");Hiba és javítás
A paraméter értéke egy állandó szöveg (fizetes), amely szerint az adatbázis rendez, de mivel minden sorban ugyanaz, a sorrend nem változik. Az oszlopnév nem paraméterezhető. A javítás: az ORDER BY után a program rögzített szövegeiből választott részt fűzd az SQL-hez ("... ORDER BY " + sorrend), a sorrend értéke pedig a SelectedIndex alapján választódjon ki.
2. A LIKE nem talál semmit
parancs.Parameters.AddWithValue("@minta", nevresz);Hiba és javítás
A LIKE a mintát a teljes szöveggel hasonlítja össze. % nélkül csak a pontosan azonos szöveget találja meg (a ko nem találja a Kovács nevet). Fűzd a mintát: "%" + nevresz + "%".
3. Az ékezetes név nem található
Az árpád keresés nem találja meg az Árpád nevet, pedig az angol betűs nevek keresésénél a kis- és nagybetű nem számít. Az SQLite Ok és javítás
LIKE csak az ASCII betűknél hagyja figyelmen kívül a kis- és nagybetű különbségét; az á és az Á eltér. A megoldás lehetőségei: (1) kérd meg a felhasználót, hogy pontosan írja be a nevet, (2) a kereséskor mindkét változatot (kis- és nagybetűs első betű) is keresed, (3) az adatok mellé tárolsz egy kisbetűs, ékezet nélküli keresőoszlopot, vagy (4) a szűrést a program oldalán végzed a DataTable sorain. Ezek közül a kezdő szinten a 4. a legegyszerűbb, és a 3.8 leckében ezt is megnézzük.
4. Hiányzó zárójel
WHERE vnev LIKE @minta OR knev LIKE @minta AND fizetes >= @minHiba és javítás
Az AND erősebb, ezért ez azt jelenti: vnev LIKE @minta, vagy (knev LIKE @minta és a fizetés elég magas). A vezetéknévre keresésnél tehát a fizetési szűrő nem érvényesül. Zárójelezd: (vnev LIKE @minta OR knev LIKE @minta) AND fizetes >= @min.
5. NullReferenceException az ablak indulásakor
string varos = cmbVaros.SelectedItem.ToString();Hiba és javítás
Ha a Frissit() még azelőtt lefut, hogy a cmbVaros kapott volna kiválasztott elemet (SelectedItem értéke null), a ToString() hibát okoz. Védekezz kétféleképpen: a betoltve jelzővel kilépsz a korai futásból, és a SelectedIndex <= 0 feltétellel kezeled a hiányzó kiválasztást.
6. A NULL fizetésű dolgozó eltűnik
Egy dolgozónak nincs megadva a fizetése, és a kereső soha nem mutatja, pedig a minimum 0. A Ok és javítás
fizetes >= 0 a NULL értékre nem igaz, ezért a sor kimarad. Ha mutatni szeretnéd, ezt kérni kell: AND (fizetes >= @min OR fizetes IS NULL). A jobb megoldás: az adatbázisban a fizetés legyen NOT NULL és alapértelmezett 0 (DEFAULT 0), ezzel kizárod a hiányzó értéket.
Mini projekt: dolgozói kereső
Építsd meg a keresőt, és bővítsd egy extra szűrővel:
- Az
adatoktábla legyen feltöltve a leckében látott 9 sorral (köztük a címnélkülivel). - A
DB.Dolgozokés aDB.Varosokmetódus, az ablak a négy szűrővel és a találati táblázattal. - Új szűrő: egy
nudMaxFizetesmező a legnagyobb fizetéshez (alapérték 1 000 000), amely aBETWEENsegítségével szűr a két határ között. - A
lblDarabmutassa a találatok számát, és ha nincs találat, üzenet: Nincs a feltételeknek megfelelő dolgozó. - Teszteld: ékezetes név, nagybetűs keresés, üres név, nulla találat, a szűrők együttes használata.
Megoldás megnyitása (próbáld ki előbb önállóan!)
A DB.Dolgozok kap egy ötödik paramétert (int maxFizetes), a lekérdezés pedig a fizetes >= @min AND fizetes <= @max feltételt (vagy BETWEEN @min AND @max) használja. A nudMaxFizetes.ValueChanged esemény is a SzuroValtozott metódust hívja. A hibás határokat (a legkisebb nagyobb a legnagyobbnál) érdemes külön jelezni.
// DB.cs: a lekérdezés új feltétele
+ "AND fizetes BETWEEN @min AND @max "
parancs.Parameters.AddWithValue("@max", maxFizetes);
// Form1.cs: a Frissit() metódusban
if (nudMinFizetes.Value > nudMaxFizetes.Value)
{
lblDarab.Text = "A legkisebb fizetés nem lehet nagyobb a legnagyobbnál!";
return;
}
dgvDolgozok.DataSource = tabla;
if (tabla.Rows.Count == 0)
{
lblDarab.Text = "Nincs a feltételeknek megfelelő dolgozó.";
}
else
{
lblDarab.Text = tabla.Rows.Count + " találat";
}Mit tegyél ide: a kész kereső a két fizetéshatárral, a „Győr” város szűrőjével és a rendezéssel, néhány találattal.Javasolt fájlnév: winforms-3-5-kesz.webp · Alt szöveg: A kész dolgozói kereső több szűrővel
Három önálló gyakorlófeladat
Egyszerre csak egyet csinálj: tervezd meg, írd meg, futtasd, ellenőrizd, és csak utána nyisd ki a megoldást.
1. Város szerinti csoportosítás
Az ablakon egy gomb írja ki, hány dolgozó él az egyes városokban (Győr: 3), egy A Az lstStat ListBoxban.Egy lehetséges megoldás
GROUP BY csoportokba rendezi a sorokat, a COUNT(*) csoportonként számol. A NULL cím külön csoportot alkot, ezért kihagyjuk.private void btnStat_Click(object sender, EventArgs e)
{
lstStat.Items.Clear();
using (SQLiteConnection kapcsolat = DB.UjKapcsolat())
{
kapcsolat.Open();
using (SQLiteCommand parancs = new SQLiteCommand("SELECT cim, COUNT(*) AS darab FROM adatok WHERE cim IS NOT NULL GROUP BY cim ORDER BY cim", kapcsolat))
using (SQLiteDataReader olvaso = parancs.ExecuteReader())
{
while (olvaso.Read())
{
lstStat.Items.Add(olvaso["cim"] + ": " + olvaso["darab"]);
}
}
}
}ExecuteReader sorról sorra olvas: a Read() addig igaz, amíg van következő sor. (Hibakezelést a try–catch blokkal érdemes hozzátenni.)
2. A legjobban fizetett három
Egy gomb jelenítse meg a táblázatban a három legjobban fizetett dolgozót. Az Egy lehetséges megoldás
ORDER BY ... DESC LIMIT 3 pontosan ezt adja. A lekérdezés rögzített szöveg, nincs benne felhasználói bevitel.DataTable tabla = new DataTable();
using (SQLiteConnection kapcsolat = DB.UjKapcsolat())
{
kapcsolat.Open();
using (SQLiteDataAdapter adapter = new SQLiteDataAdapter("SELECT vnev, knev, fizetes FROM adatok ORDER BY fizetes DESC LIMIT 3", kapcsolat))
{
adapter.Fill(tabla);
}
}
dgvDolgozok.DataSource = tabla;
3. Fizetési sáv választó
Egy A három sávhoz három rögzített feltétel-szöveg tartozik, amelyek közül a sorszám alapján választunk (nem a felhasználó szövegéből építjük). Az alsó határ a cmbSav lista három sávot kínál: 300 000 alatt, 300 000 – 400 000, 400 000 fölött. A kiválasztott sáv szerint szűrjön a program.Egy lehetséges megoldás
BETWEEN miatt része a sávnak: ha ezt nem szeretnéd, használj > és < jeleket.string feltetel = "fizetes < 300000";
if (cmbSav.SelectedIndex == 1)
{
feltetel = "fizetes BETWEEN 300000 AND 400000";
}
else if (cmbSav.SelectedIndex == 2)
{
feltetel = "fizetes > 400000";
}
string sql = "SELECT vnev, knev, fizetes FROM adatok WHERE " + feltetel + " ORDER BY fizetes";
Gyakorlótár: 6 további feladat
Három szinten gyakorolhatsz: alap, közepes és kihívás. Az első négyet a DB Browser Execute SQL lapján oldd meg, a többihez a dolgozói kereső projektje kell. Csak a próbálkozás után nyisd le a megoldást.
Alap szint
1. Veszprémi dolgozók névsorban
Kérdezd le a veszprémi dolgozók vezeték- és keresztnevét, vezetéknév szerint ábécébe rendezve. A szűrés a Megoldás megnyitása
WHERE, a rendezés az ORDER BY dolga. A kért oszlopokat a SELECT után soroljuk fel.SELECT vnev, knev
FROM adatok
WHERE cim = 'Veszprém'
ORDER BY vnev;
2. Fizetési sáv
Írd ki azokat a dolgozókat, akiknek a fizetése 350 000 és 420 000 Ft között van (a határokat is beleértve), fizetés szerint növekvő sorrendben. A Megoldás megnyitása
BETWEEN mindkét határt tartalmazza. Ugyanez >= és <= jelekkel is megírható.SELECT vnev, knev, fizetes
FROM adatok
WHERE fizetes BETWEEN 350000 AND 420000
ORDER BY fizetes;
Közepes szint
3. Több város és kizárás
Írd ki a győri és a pécsi dolgozókat ( A IN), majd azokat, akik nem ezekben a városokban laknak (NOT IN). Mi történik a címnélküli dolgozóval a második lekérdezésben?Megoldás megnyitása
NOT IN a NULL értékű sort is kihagyja, mert a NULL-lal végzett összehasonlítás nem igaz. Ha a címnélküli sor is kell, az OR cim IS NULL feltételt hozzá kell tenni.SELECT vnev, knev, cim FROM adatok WHERE cim IN ('Győr', 'Pécs');
SELECT vnev, knev, cim FROM adatok WHERE cim NOT IN ('Győr', 'Pécs');
SELECT vnev, knev, cim FROM adatok WHERE cim NOT IN ('Győr', 'Pécs') OR cim IS NULL;
4. A legkisebb fizetés
Add meg egyetlen lekérdezéssel a legkisebb fizetést kapó dolgozó nevét. Két megoldást írj: Az első megoldás a legegyszerűbb: növekvő rendezés, az első sor. A második egy al-lekérdezést (zárójelben álló lekérdezést) használ: előbb kiszámolja a legkisebb fizetést, majd azt keresi a táblában. A második megoldás több sort is ad, ha többen keresnek ugyanannyit.MIN nélkül (ORDER BY és LIMIT), és MIN segítségével (al-lekérdezéssel).Megoldás megnyitása
SELECT vnev, knev, fizetes FROM adatok ORDER BY fizetes ASC LIMIT 1;
SELECT vnev, knev, fizetes FROM adatok
WHERE fizetes = (SELECT MIN(fizetes) FROM adatok);
Kihívás szint
5. Kereső fizetéssávval
Bővítsd a dolgozói keresőt: két mező ( A határok ellentmondását az adatbázis-hívás előtt ellenőrizzük. A hibás sávnál a lekérdezés üres eredményt adna, de a felhasználónak érdemes megmondani, miért.nudMinFizetes, nudMaxFizetes) szabja meg a sávot, és ha a minimum nagyobb a maximumnál, a program ne kérdezzen, hanem jelezzen.Megoldás megnyitása
private void Frissit()
{
if (!betoltve)
{
return;
}
if (nudMinFizetes.Value > nudMaxFizetes.Value)
{
lblDarab.Text = "A legkisebb fizetés nem lehet nagyobb a legnagyobbnál!";
return;
}
// ... a lekérdezés a DB.Dolgozok(...) hívással, a max értékkel is ...
}
6. A kereső címnélküli sorokkal
Szeretnéd, hogy a kereső a A hiányzó értékeket külön kell engedélyezni az NULL fizetésű vagy NULL című dolgozókat is mutassa, amikor a szűrők alaphelyzetben vannak (a városszűrő (összes), a minimum 0). Hogyan módosítod a lekérdezést?Megoldás megnyitása
IS NULL segítségével. Fontos, hogy a három feltétel zárójelezése helyes legyen, különben az OR a többi szűrőt is felborítja. A város szűrőjénél a (@varos = '' OR cim = @varos) már minden sort átenged üres szűrőnél, így a NULL című sor ott nem akad el. A fizetésnél kell az új feltétel.string sql = "SELECT id, vnev, knev, fizetes, cim FROM adatok "
+ "WHERE (vnev LIKE @minta OR knev LIKE @minta) "
+ "AND (fizetes >= @min OR (fizetes IS NULL AND @min = 0)) "
+ "AND (@varos = '' OR cim = @varos) "
+ "ORDER BY " + sorrend;
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. Szűri a sorokat: csak azok kerülnek az eredménybe, amelyekre a feltétel igaz. Mintaillesztésre. A Mert a Az Mert ORDER BY nélkül nincs garantált sorrend, így nem tudod, melyik n sort kapod. A paraméter mindig érték, nem a lekérdezés szerkezetének része. Az oszlopnevet a program rögzített szövegei közül választva fűzzük az SQL-hez, soha nem a felhasználó beírt szövegéből. Az 1. Mit csinál a WHERE?
2. Mire való a LIKE, és mit jelent a % jel?
% bármennyi (akár nulla) karaktert jelent, a _ pontosan egyet.3. Miért nem működik a = NULL?
NULL ismeretlen érték, és a vele végzett összehasonlítás sem igaz, sem hamis. A hiányzó értéket az IS NULL vizsgálja.4. Mi a különbség az ASC és a DESC között?
ASC növekvő, a DESC csökkenő sorrend. Az ASC az alapértelmezett.5. Miért kell a LIMIT mellé ORDER BY?
6. Miért nem lehet az oszlopnevet paraméterként átadni?
7. Hogyan lesz egy szűrő választható egyetlen lekérdezésben?
(@szuro = '' OR oszlop = @szuro) mintával: üres szűrőnél az első rész igaz, így a feltétel mindent átenged.
Mit tudsz már?
- Használod a
WHEREfeltételeit, és helyesen zárójelezed azANDésORkapcsolatokat. - Tudod, hogyan viselkedik a
NULLaz összehasonlításoknál. - Rendezel az
ORDER BY, szűrsz aDISTINCTés aLIMITsegítségével. - Választható szűrőket építesz egyetlen paraméteres lekérdezésbe.
- Tudod, miért nem paraméterezhető a rendezés, és hogyan oldod meg biztonságosan.
Következő lecke: INSERT, UPDATE és DELETE
Eddig adatokat olvastál. A következő leckében módosítod is őket: új sort veszel fel, meglévőt javítasz, és törölsz.




