NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.

Lekce 5 - SqlDataReader a připojená databáze v C# .NET

V předchozím kvízu, Kvíz - Databáze, přístupy, připojená aplikace v C#- ADO.NET , jsme si ověřili nabyté zkušenosti z předchozích lekcí.

V dnešním C# .NET tutoriálu se naučíme číst z databáze jednotlivé řádky.

Zpracování dat

Pokud potřebujeme spustit nad databází dotaz, který vrací více záznamů (ten náš poslední vracel jen jedno číslo), musíme ke zpracování výsledku dotazu využít třídu *DataReader. Instanci této třídy jako výsledek vrátí metoda ExecuteReader() třídy Command. Třída *DataReader umožňuje procházet výslednou množinu dat po jednotlivých záznamech. K tomu slouží metoda Read(). Přístup k jednotlivým atributům záznamu můžeme získat pomocí indexu nebo názvu sloupce uvedeného v hranatých závorkách, případně pomocí metod Get...(), které nám hodnoty rovnou převedou na požadovaný datový typ.

Příklad 4

Vypište na obrazovku všechna slovíčka. U slovíček budeme chtít vypsat sloupce: Id, Czech a English.

Řešení

SqlCommand prikaz = new SqlCommand("SELECT Id, Czech, English FROM Word", pripojeni);
pripojeni.Open();
SqlDataReader dataReader = prikaz.ExecuteReader();
while (dataReader.Read()) // dokud neprojdeme všechny záznamy
{
    Console.WriteLine("{0} {1} {2}",
        dataReader[0],                      // index sloupce (Id)
        dataReader["Czech"],                // název sloupce
        dataReader.GetString(2));           // index sloupce (English) s převedením na požadovaný datový typ
}

Výsledek:

Konzolová aplikace
1 počítač computer
2 míč ball
3 pes dog
4 já I
5 mít rád like
6 devbook devbook

SQL dotaz místo COUNT nyní obsahuje výčet sloupců, které vybíráme. SqlDataReader čte řádek po řádku co databáze vrátila a výsledky vypisuje do konzole.

Předávání parametrů

Udělejme z aplikace opravdový slovníček a nechme uživatele zadat slovíčko, které mu následně přeložíme.

SQL injekce

Nejprve si ukažme, jak se to nemá dělat. Naivně bychom si mohli nechat zadat slovíčko a to potom přímo vložit jako vyhledávanou frázi do dotazu. Zdrojový kód aplikace by vypadal takto:

// tento zdrojový kód je nebezpečný
string connectionString = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=SlovickaDB;Integrated Security=True";
using (SqlConnection pripojeni = new SqlConnection(connectionString))
{
    pripojeni.Open();

    Console.WriteLine("Zadej anglické slovíčko k překladu");
    string slovo = Console.ReadLine();

    SqlCommand prikaz = new SqlCommand("SELECT Czech FROM Word WHERE English='" + slovo + "'", pripojeni);

    SqlDataReader dataReader = prikaz.ExecuteReader();
    while (dataReader.Read()) // dokud neprojdeme všechny záznamy
    {
        Console.WriteLine("Překlad: {0}", dataReader["Czech"]);
    }
}
Console.ReadKey();

SQL dotaz je podobný tomu předchozímu. Nezajímají nás však již všechny řádky, ale jen ty, kde má sloupec English určitou hodnotu. Podmínku v SQL zapíšeme pomocí klauzule WHERE.

Ačkoli se zdá, že aplikace funguje korektně:

Konzolová aplikace
Zadej anglické slovíčko k překladu
computer
Překlad: počítač

Zamyslete se nad tím, co se stane, když nějaký uživatel zadá k překladu tento řetězec:

'; DROP TABLE Word --

Škodlivý kód se nám vloží přímo do dotazu a spustí se nad databází. Útočníkovi tak dáváme plnou kontrolu and našimi daty, v tomto případě nám nenávratně vymaže celou tabulku. To je ještě poměrně nevinný útok, mohl by nám vzít i hesla uživatelů a podobně.

Předávání parametrů

Bezpečnostní problém způsobuje samozřejmě přímé vkládání hodnot do textu SQL dotazu. Útok se proto nazývá SQL injection, jako vložení cizího SQL kódu do našeho.

Platí zásada, že musíme počítat s tím, že škodlivý kód může být v každém parametru, který do dotazu vkládáme. Nelze se spolehnout na to, že tato proměnná asi nebude nic od uživatele obsahovat.

Aplikace se mění a do proměnné by se mohla časem dostat i třeba jen část hodnoty, kterou zadal uživatel. A věřte mi, že uživatelé jsou vynalézaví a budou naši aplikaci zkoušet a budou nám tam tyto hodnoty vkládat.

V minulosti se parametry ošetřovaly speciální funkcí, která tzv. zescapovala škodlivé znaky. Moderní dotazy se píší pomocí tzv. Prepared Statements. Ty fungují tak, že se do dotazu místo parametrů vloží jen speciální značky. Parametry se poté předávají odděleně. Ukažme si, jak do dotazu vložit parametry správně:

string connectionString = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=SlovnicekDB;Integrated Security=True";
using (SqlConnection pripojeni = new SqlConnection(connectionString))
{
    pripojeni.Open();

    Console.WriteLine("Zadej anglické slovíčko k překladu");
    string slovo = Console.ReadLine();

    SqlCommand prikaz = new SqlCommand("SELECT Czech FROM Word WHERE English=@slovo", pripojeni);
    prikaz.Parameters.AddWithValue("@slovo", slovo);

    SqlDataReader dataReader = prikaz.ExecuteReader();
    while (dataReader.Read()) // dokud neprojdeme vsechny zaznamy
    {
        Console.WriteLine("Překlad: {0}", dataReader["Czech"]);
    }

}
Console.ReadKey();

Všimněte si, že v SQL dotazu je jen zástupná značka, která se označuje zavináčem @ a libovolným názvem. Nepíšeme kolem ní ani apostrofy, ty jsou dodány později podle typu značky. Před zavoláním metody ExecuteReader() do dotazu připojíme parametry, v našem případě parametr @slovo, jehož hodnotou bude proměnná slovo. Databáze si sama parametry ošetří a nemusíme se bát, že by nám aplikaci někdo mohl nabourat.

V příští lekci, Databáze v C# .NET - INSERT, UPDATE, DELETE a COUNT, si ukážeme, jak záznamy v databázi přidávat, mazat a editovat. Zdrojové kódy dnešního programu jsou jako vždy v příloze ke stažení.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 455x (1.03 MB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Kvíz - Databáze, přístupy, připojená aplikace v C#- ADO.NET
Všechny články v sekci
Databáze v C# - ADO.NET
Přeskočit článek
(nedoporučujeme)
Databáze v C# .NET - INSERT, UPDATE, DELETE a COUNT
Článek pro vás napsal JOF
Avatar
Uživatelské hodnocení:
122 hlasů
Aktivity