4. díl - MS-SQL krok za krokem: Výběr dat (vyhledávání)

MS-SQL krok za krokem MS-SQL krok za krokem: Výběr dat (vyhledávání)

V minulém dílu seriálu tutoriálů o MS-SQL databázi jsme si ukázali vkládání a mazání záznamů. Dnes se zaměříme na tu nejhezčí část a tou je výběr dat. Jedná se o dotazování na data, jestli chcete, tak vyhledávání v tabulce.

Výběr dat je klíčovou funkcí databází, umožňuje nám totiž pomocí relativně jednoduchých dotazů dělat i složité výběry dat. Od prostého výběru uživatele podle jeho id (např. pro zobrazení detailů v aplikaci) můžeme vyhledávat uživatele splňující určité vlastnosti, výsledky řadit dle různých kritérií nebo dokonce do dotazu zapojit více tabulek, různé funkce a skládat dotazy do sebe (o tom až v dalších dílech).

Testovací data

Před zkoušením dotazů je vždy dobré mít nějaká testovací data, abychom měli s čím pracovat a neměli tam jen 4 uživatele. Pojďme si do naší tabulky uzivatele vložit nějaké záznamy, aby bylo s čím pracovat. Něco jsem vám připravil. Tabulku si nejprve vyprázdněte (abychom měli stejná data):

DELETE FROM [Uzivatele];

Dále spusťte následující SQL dotaz:

INSERT INTO [Uzivatele] (
        [Jmeno],
        [Prijmeni],
        [DatumNarozeni],
        [PocetClanku]
)
VALUES
('Jan',  'Novák',  '1984-11-03', 17),
('Tomáš', 'Marný', '1942-10-17', 12),
('Josef', 'Nový', '1958-7-10', 5),
('Alfons', 'Svoboda', '1935-5-15', 6),
('Ludmila', 'Dvořáková', '1967-4-17', 2),
('Petr', 'Černý', '1995-2-20', 1),
('Vladimír', 'Pokorný', '1984-4-18', 1),
('Ondřej', 'Bohatý', '1973-5-14', 3),
('Vítězslav', 'Churý', '1969-6-2', 7),
('Pavel', 'Procházka', '1962-7-3', 8),
('Matěj', 'Horák', '1974-9-10', 0),
('Jana', 'Veselá', '1976-10-2', 1),
('Miroslav', 'Kučera', '1948-11-3', 1),
('František', 'Veselý', '1947-5-9', 1),
('Michal', 'Krejčí', '1956-3-7', 0),
('Lenka', 'Němcová', '1954-2-11', 5),
('Věra', 'Marková', '1978-1-21', 3),
('Eva', 'Kučerová', '1949-7-26', 12),
('Lucie', 'Novotná', '1973-7-28', 4),
('Jaroslav', 'Novotný', '1980-8-11', 8),
('Petr', 'Dvořák', '1982-9-30', 18),
('Jiří', 'Veselý', '1961-1-15', 2),
('Martina', 'Krejčí', '1950-8-29', 4),
('Marie', 'Černá', '1974-2-26', 5),
('Věra', 'Svobodová', '1983-3-2', 2),
('Pavel', 'Dušín', '1991-5-1', 9),
('Otakar', 'Kovář', '1992-12-17', 9),
('Kateřina', 'Koubová', '1956-11-15', 4),
('Václav', 'Blažek', '1953-10-20', 6),
('Jan', 'Spáčil', '1967-5-6', 3),
('Zdeněk', 'Malačka', '1946-3-10', 6);

V databázi máme 31 uživatelů. To by mělo stačit k tomu, abyste si na nich vyzkoušeli základy dotazování.

(Mimochodem, všimněte si, že se dá VALUES v příkazu INSERT vložit najednou více, vloží se tak více položek v jednom dotazu).

Dotazování

Dotaz na data, tedy jejich vyhledání/výběr jsme již vlastně viděli, když jsme řádek přidávali. Pro rekapitulaci zobrazíte všechny data kliknutím pravým tlačítkem na tabulku a Show Table Data.

Data ve Visual Studiu

Designer Visual Studia byl pro nás zpočátku takovou berličkou, ale nyní pro nás již přestává být zajímavý. Dorážíme totiž na jeho hranice, jediné co zde můžeme omezit, je počet řádků. Do políčka Max Rows zadejte třeba 10 a potvrďte. Na databázi se zavolá dotaz, který vybere pouze 10 prvních položek. To se hodí pokud je databáze rozsáhlá, abyste neposílali úplně všechno, pokud chcete všechna data (a nevíte kolik jich je), tak z nabídky zvolíte All.

Na pozadí Visual Studio posílá do databáze samozřejmě T-SQL dotaz, který může vypadat třeba následovně:

SELECT TOP 10 * FROM [Uzivatele]

Příkaz je asi docela srozumitelný, TOP 10 říká, že chceme 10 řádku z vrchu (prvních 10) a ta hvězdička označuje, že chceme vybrat všechny sloupce. Dotaz tedy česky zní: "Vyber prvních 10 řádků a všechny sloupce z tabulky Uzivatele".

Výsledek dotazu nám Visual Studio zobrazí, měli byste vidět toto:

8       Jan        Novák      1984-11-03       17
9       Tomáš      Marný      1942-10-17     12
10      Josef      Nový       1958-07-10       5
11      Alfons     Svoboda    1935-05-15        6
12      Ludmila    Dvoráková  1967-04-17      2
13      Petr       Cerný      1995-02-20       1
14      Vladimír   Pokorný    1984-04-18      1
15      Ondrej     Bohatý     1973-05-14       3
16      Vítezslav  Churý      1969-06-02      7
17      Pavel      Procházka  1962-07-03       8

WHERE

Dost často potřebujeme získat data na základě určitých kritérií. Například budeme hledat pouze Jany. K tomuto účelu se používá klauzule WHERE, kde se udávají podmínky ve formátu sloupec operátor hodnota. Základní operátory =, >, <, >=, <=, != určitě umíte použít. Složitější si ukážeme dále v tomto dílu. Dotaz pro vyhledání Janů by vypadal následovně.

SELECT * FROM [Uzivatele] WHERE [Jmeno] = 'Jan';

Zde jsem vypustil TOP 10, abych dostal všechny Jany.

Tabulky mají většinou hodně sloupců a většinou nás zajímají jen nějaké. Abychom databázi nezatěžovali přenášením zbytečných dat zpět do naší aplikace, budeme se snažit vždy specifikovat ty sloupce, které chceme. Dejme tomu, že budeme chtít jen příjmení lidí, co se jmenují Jan a ještě počet jejich článků. Dotaz upravíme:

SELECT [Prijmeni], [PocetClanku] FROM [Uzivatele] WHERE [Jmeno] = 'Jan';

Výsledek:

Novák     17
Spáčil    3

Opravdu nebuďte líní a pokud nepotřebujete téměř všechny sloupce, vyjmenujte v SELECTu ty, jejichž hodnoty vás v tu chvíli zajímají. Vždy se snažte podmínku omezit co nejvíce již na úrovni databáze, ne že si vytaháte celou tabulku do aplikace a tam si ji vyfiltrujete. Řekněme, že by vaše aplikace poté nebyla úplně rychlá :) Výčet sloupců, které má dotaz vrátit, nemá nic společného s dalšími sloupci, které v dotazu používáme. Můžeme tedy vyhledávat podle deseti sloupců, ale vrátit jen jeden.

Stejně jako tomu bylo u DELETE, i zde bude fungovat pouze dotaz:

SELECT * FROM [Uzivatele];

Tehdy budou vybráni úplně všichni uživatelé z tabulky.

Teď vyberme všechny uživatele, narozené po roce 1960 a s počtem článků vyšším než 5:

SELECT * FROM [Uzivatele] WHERE [DatumNarozeni] >= '1960-1-1' AND [PocetClanku] > 5;

Výsledek:

8     Jan          Novák        1984-11-03    17
16    Vítezslav    Churý        1969-06-02    7
17    Pavel        Procházka    1962-07-03    8
27    Jaroslav     Novotný      1980-08-11    8
28    Petr         Dvořák       1982-09-30    18
33    Pavel        Dušín        1991-05-01    9
34    Otakar       Kovář        1992-12-17    9

Všimněte si v dotazu slova AND, to určuje, že podmínky musí být splněny obě. Pokud chcete, aby se do výsledku zařadilo vše, co splňuje alespoň jednu podmínku, místo AND použijte OR, dotaz by pak česky zněl: "Vyber všechny sloupce uživatelů, kteří se narodili po roce 1960 nebo napsali víc než 5 článků".

Operátory

V SQL máme i další operátory, řekněme si o LIKE, IN a BETWEEN.

LIKE

Like umožňuje vyhledávat textové hodnoty jen podle části textu. Funguje podobně, jako operátor "=" (rovná se), pouze můžeme používat 2 zástupné znaky:

  • % (procento) označuje libovolný počet libovolných znaků.
  • _ (podtržítko) označuje jeden libovolný znak.

Pojďme si vyzkoušet několik dotazů s operátorem LIKE. Najděme příjmení lidí začínající na S:

SELECT [Prijmeni] FROM [Uzivatele] WHERE [Prijmeni] LIKE 's%';

Text zadáme jako vždy v apostrofech, pouze na některá místa můžeme vložit speciální znaky. Na velikosti písmen nezáleží (hledání je tedy case-insensitive). Výsledek dotazu bude následující:

Svoboda
Svobodová
Spáčil

Nyní zkusme najít pětipísmenná příjmení, která mají jako 2. znak O. Je obecně doporučováno odstraňovat v hodnotách předávaných LIKE bílé znaky. Toho docílíte funkcemi LTRIM() a RTRIM(), které odstraňují bílé znaky zleva a zprava:

SELECT [Prijmeni] FROM [Uzivatele] WHERE RTRIM([Prijmeni]) LIKE '_o___';

Výsledek:

Novák
Horák
Kovář

Asi již tušíte, jak LIKE funguje. Použití lze vymyslet hodně, většinou se používá s procenty na obou stranách pro fulltextové vyhledávání (např. slova v textu článku).

IN == IN umožňuje vyhledávat pomocí výčtu prvků. Udělejme si tedy výčet jmen a vyhledejme uživatelé s těmito jmény:

SELECT [Jmeno], [Prijmeni] FROM [Uzivatele] WHERE [Jmeno] IN ('Petr', 'Jan', 'Kateřina');

Výsledek:

Jan         Novák
Petr        Černý
Petr        Dvořák
Kateřina    Koubová
Jan         Spáčil

Operátor IN se používá ještě u tzv. poddotazů, ale na ty máme ještě dost času :)

BETWEEN

Poslední operátor, který si dnes vysvětlíme, je BETWEEN (tedy mezi). Není ničím jiným, než zkráceným zápisem podmínky ">= AND <=". Již víme, že i datumy můžeme normálně porovnávat, najděme si uživatele, kteří se narodili mezi lety 1980 a 1990:

SELECT [Jmeno], [Prijmeni], [DatumNarozeni] FROM [Uzivatele] WHERE [DatumNarozeni] BETWEEN '1980-1-1' AND '1990-1-1';

Mezi 2 hodnoty píšeme AND.

Výsledek:

Jan         Novák        1984-11-03
Vladimír    Pokorný      1984-04-18
Jaroslav    Novotný      1980-08-11
Petr        Dvořák       1982-09-30
Věra        Svobodová    1983-03-02

To je pro dnešek vše. U výběru dat zůstaneme ještě několik dílů, vlastně většinu tohoto seriálu. Příště se podíváme na řazení a agregační funkce.


 

  Aktivity (1)

Článek pro vás napsal Michal Žůrek (misaz)
Avatar
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.

Jak se ti líbí článek?
Celkem (10 hlasů) :
4.64.64.64.64.6


 



 

 

Komentáře

Avatar
Maros2470
Člen
Avatar
Maros2470:

Mám dotaz. Jak dostanu ve Form do příkazu hodnotu např. z TextBoxu?

Příklad: SELECT [Prijmeni] FROM [Uzivatele] WHERE [Prijmeni] LIKE 's%'; 's%'potřebuji nahradit textem z TextBoxu.

Výsledná data načítám např. do dataGrid

 
Odpovědět 5.5.2014 19:15
Avatar
Odpovídá na Maros2470
Michal Žůrek (misaz):

no tak nahrazení asi zvládneš, nezapomeň si to ošetřit na SQL injekce. Z formuláře musíš do DB tento T-SQL kód odeslat a datagrid naplnit daty.

Odpovědět 5.5.2014 19:34
Nesnáším {}, proto se jim vyhýbám.
Avatar
Maros2470
Člen
Avatar
Odpovídá na Michal Žůrek (misaz)
Maros2470:

Když to mám napsáno takto:

private void bankaTextBox_Tex­tChanged(object sender, EventArgs e)
{
string connectionString = @"Data Source=PCMAREK\E­li;Initial Catalog=Eli-elektro;Integrated Security=True";
using (SqlConnection spojeni = new SqlConnection(con­nectionString))
{
spojeni.Open();

string kod = kodTextBox.Text;
string dotaz = "SELECT * FROM Banky WHERE Kod=@kod ";
using (SqlDataAdapter adapter = new SqlDataAdapter(do­taz, spojeni))
using (DataSet vysledky = new DataSet())
{
adapter.Selec­tCommand.Para­meters.AddWit­hValue("@kod", kod);
adapter.Fill(vys­ledky);

foreach (DataRow radek in vysledky.Tables[0]­.Rows)
{
dataGridView1­.Rows.Add(radek["Id"], radek["Banka"], radek["Kod"]);

}
}
spojeni.Close();
}

Vyhledá mi to data podle celého stringu napsaného do TextBoxu, ale nevím jak to udělat, aby mi to vypisovalo data postupně tak jak se připisují jednotlivé znaky do Text boxu.

 
Odpovědět 5.5.2014 19:52
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na Maros2470
Milan Křepelka:

Nehledal bych tam žádná kouzla, prostě to slož jako bys psal normální SQL
WHERE Kod LIKE @kod

adapter.SelectCommand.Parameters.AddWithValue("@kod", string.Format("{0}{1}",kod,"%"));

Jinak je tam dost prostor k optimalizaci. Asi není předpoklad že v průběhu života toho formuláře vznikne nová banka, takže vytvářet nový spojení na každý stisk tlačítka je vysloveně plýtvání.

 
Odpovědět 20.7.2014 16:14
Avatar
KlimiCZ
Člen
Avatar
KlimiCZ:

Je tu tlačítko "Vložit Kod" - přidávám screen kdyby jsi to stále neviděl :)

Odpovědět 20.7.2014 17:13
Nesnaž se zakrýt něco, co jsi provedl úmyslně. Svět je tak malý, že dotyčný se to stejně dozví.
Avatar
mkub
Redaktor
Avatar
Odpovídá na KlimiCZ
mkub:

ja ani nepouzivam to tlacitko ;)

 
Odpovědět 20.7.2014 18:45
Avatar
KlimiCZ
Člen
Avatar
Odpovídá na mkub
KlimiCZ:

Když nedáváš kod :D

Odpovědět 20.7.2014 18:50
Nesnaž se zakrýt něco, co jsi provedl úmyslně. Svět je tak malý, že dotyčný se to stejně dozví.
Avatar
mkub
Redaktor
Avatar
Odpovídá na KlimiCZ
mkub:

myslis? mimochodom, ja na pridavanie kodu nepotrebujem ani mys... tam, kde chcem hodit kod, tam vlozim znacku, ze dalsi text sa jedna o kod... a vysledok je rovnaky ;)

 
Odpovědět  +1 20.7.2014 20:01
Avatar
Ľubomír Prokopovič:

Len taka mensia poznamka v databaze je 31 uzivatelov nie 38 :)

Odpovědět  +1 26.8.2014 12:13
"Počítače jsou jako Bůh ve Starém zákoně - hodně příkazů a žádné slitování." Joseph Campbell
Avatar
Odpovědět 26.8.2014 12:16
Nesnáším {}, proto se jim vyhýbám.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.