4. díl - Připojená databázová aplikace v C# .NET

C# .NET Databáze Připojená databázová aplikace v C# .NET

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulém dílu našeho seriálu tutoriálů o databázích v C# .NET jsme si popsali různé přístupy pro práci s databází v objektových jazycích a také technologie, které jsou v .NET frameworku pro tyto účely obsaženy. Dnes si ukážeme základy práce s databázi pomocí připojeného přístupu.

Pozn.: Všude v dalším textu, kde se před názvem třídy objeví *, ji můžete nahradit příslušným poskytovatelem dat.

Založte si nový projekt, konzolovou aplikaci, kterou pojmenujte SlovickaSQL.

Získání ConnectionStringu

Abyste se mohli k DB připojit, potřebujete tzv. ConnectionString. To je řetězec, který obsahuje údaje potřebné k připojení k databázi. Typicky je zde název databáze a případně heslo.

Ve Visual Studio si zobrazte Database Explorer (View -> Other Windows -> Database Explorer), ve starších verzích VS se toto okno jmenuje Server Explorer. Přidáme nové připojení a v následujícím dialogu zkontrolujeme, že máme v DataSource nastaveno "Microsoft SQL Server (SqlClient)". Do Server name zadáme "localhost\JME­NO_VASEHO_SER­VERU" a dole vybereme naši databázi SlovnicekDB. Spojení můžete otestovat tlačítkem Test Connection. Potvrdíme.

Jakmile nové spojení v Database Exploreru označíte a pravým zvolíte Properties, bude vám zobrazen ConnectionString. Ten si někam zkopírujte, můj vypadá takto:

Data Source=localhost\MSSQLSERVER2008;Initial Catalog=SlovnicekDB;Integrated Security=True

Váš SQL server se bude dost možná jmenovat SQLEXPRESS místo MSSQLSERVER2008.

SQLConnection­StringBuilder

Každý poskytovatel dat z ADO.NET potřebuje trochu jiné údaje a proto se někdy připojovací řetězec generuje pomocí třídy *ConnectionStrin­gBuilder. Stačí vytvořit instanci této třídy a naplnit její vlastnosti požadovanými hodnotami. Výsledný řetězec bude dostupný právě ve vlastnosti ConnectionString. Pokud nechcete řešit kompatibilitu s dalšími poskytovateli, můžete tento krok přeskočit a vrátit se k němu třeba později. V seriálu si řekneme od všeho trochu, účelem není aby vás to odradilo a vyvolalo dojem, jak jsou databáze složité, ale abyste měli přehled.

Příklad 1

S využitím třídy SQLConnection­StrigBuilder sestavte připojovací řetězec k naší cvičné databázi SlovnicekDB.

Řešení
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
csb.DataSource = @"localhost\SQLEXPRESS";
csb.InitialCatalog = "SlovnicekDB";
csb.IntegratedSecurity = true;
string pripojovaciRetezec = csb.ConnectionString;

Pozn.: Nezapomeňte otevřít příslušný jmenný prostor (using System.Data.SqlCli­ent;).

Připojení

Jakmile máme ConnectionString, můžeme se k DB připojit. To uděláme vytvořením instance třídy *Connection, které ConnectionString předáme v konstruktoru. Připojení pak otevřete zavoláním metody Open(). Je dobrým zvykem všechny databázové objekty tvořit v bloku using, aby došlo k rychlému zavření nepotřebných spojení. Druhým přístupem je nechávat spojení otevřené, což se dělá jen u desktopových aplikací a vyžaduje to nějaký databázový wrapper, typicky realizovaný statickou třídou.

Příklad 2

Otestujte spojení s databází s pomocí připojovacího řetězce z příkladu 1. Vypište do konzole, zda se spojení podařilo otevřít nebo ne.

Řešení

string connectionString = @"Data Source=localhost\MSSQLSERVER2008;Initial Catalog=SlovnicekDB;Integrated Security=True";
using (SqlConnection pripojeni = new SqlConnection(connectionString))
{
        pripojeni.Open();
        Console.WriteLine("Aplikace se úspěšně připojila k databázi.");
}
Console.ReadKey();

Výsledek:

Úspěšné připojení k databázi v C# .NET

Další kód budeme psát pod pripojeni.Open();

Databázové příkazy

Databázové příkazy jsou zastoupeny třídou *Command. Umožňují spustit nad připojenou databází jakýkoliv SQL dotaz. Pro jejich vytvoření tedy musíte znát syntaxi jazyka SQL (budu se je snažit trochu popsat i zde, nicméně SQL je na devbooku věnováno hned několik sekcí). U nové instance třídy *Command musíte naplnit 2 základní vlastnosti - Connection (viz příklad 2) a CommandText. Ten bude právě obsahovat SQL dotaz. Poté můžete příkaz spustit. Ke spuštění slouží metody ExecuteReader(), ExecuteScalar() a ExecuteNonQuery(). Tu první využijete tehdy, pokud SQL dotaz vrací množinu dat (většina SELECTů, např. dotaz na jedno nebo více slovíček). Druhá nalezne své uplatnění, pokud SQL dotaz vrací jedinou hodnotu (typicky SELECT s agregační funkcí, např. počet všech slovíček). Poslední se používá ke spouštění dotazů, které nevracejí žádnou hodnotu (INSERT, UPDATE, DELETE, např. vložení slovíčka). Její návratová hodnota nese informaci o počtu "ovlivněných" řádků.

Příklad 3

Vytvořte příkaz, který z připojené databáze z příkladu 2 získá počet záznamů v tabulce Word a vypíše jej na obrazovku.

Řešení

SqlCommand prikaz = new SqlCommand();
prikaz.Connection = pripojeni;
prikaz.CommandText = "SELECT COUNT(*) FROM Word";
int pocetSlovicek = (int)prikaz.ExecuteScalar();  // metoda vrací typ object - je potřeba převést na int
pripojeni.Close();
Console.WriteLine("Počet slovicek v DB je {0}", pocetSlovicek);

Výsledek:

Získání počtu záznamů v databází v C# ADO .NET

Dotaz začíná slovem SELECT (tedy vyber). SQL klauzule se většinou píší velkými písmeny. Dále následuje COUNT(*), tím říkáme, že nás zajímá počet. Hvězdička označuje, že chceme počítat s ohledem na všechny sloupce. FROM Word označuje, že data vybíráme z tabulky Word. Jednoduché, že? Mimochodem, SQL se dříve jmenovalo SEQUEL, kde ono EQUEL označovalo anglický dotazovací jazyk. Každý dotaz vypadá proto jako jednoduchá anglická věta.

Pozn.: Někteří začátečníci zjišťují počet záznamů v tabulce tak, že si načtou úplně všechny řádky i s daty a ty potom spočítají (řádky se naučíme načítat příště). Vrácený výsledek je sice stejný jako výsledek při použití COUNT, jenže jsme databázi zbytečně zatížili načtením hodnot, které vůbec nevyužijeme. Mezi "načíst jedno číslo" nebo "načíst milion slovíček jen proto, abychom zjistili, že jich je milion" je velký výkonový rozdíl :)

Příště si z databáze tedy načteme nějaká slovíčka.


 

Stáhnout

Staženo 484x (34.42 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal JOF
Avatar

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


 



 

 

Komentáře
Zobrazit starší komentáře (26)

Avatar
JOF
Tým ITnetwork
Avatar
JOF:

Ahoj,

zkus použít jiný formát - např. [Datum] = '2007-05-18'.

 
Odpovědět 1.11.2015 19:38
Avatar
Luboš
Člen
Avatar
Odpovídá na JOF
Luboš:

Zkouším to, ale pořád to nejde. Datum se mi zobrazuje takto:

Editováno 1.11.2015 20:50
 
Odpovědět 1.11.2015 20:49
Avatar
Luboš
Člen
Avatar
Luboš:

Už mi to jde. Prohodil jsem dny a měsíce. Přitom v tabulce ve VS se mi to zobrazuje správně. Neuvěřitelné.

 
Odpovědět 1.11.2015 21:22
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na Luboš
Milan Křepelka:

Na tom není nic neuvěřitelného. V podstatě je to běžná situace. Datetime format na SQL serveru je prostě jiný než prezentační formát na klientovi.

 
Odpovědět 1.11.2015 22:50
Avatar
Luboš
Člen
Avatar
Odpovídá na Milan Křepelka
Luboš:

Kdyby to bylo tak jak píšeš tak to chápu, jenomže jde o to, že mi DB uvnitř VS ukazuje už přeformátovaná data do češtiny. Takže dáš copy/paste a chceš vyhledat to co vidíš, jenže ti to nepůjde protože je to vnitřně uložené jinak a pokud neznáš dobře vnitřní nastavení jsi víš kde.

Nevíš o nějakém článku(knize) kde by se tímto tématem někdo stručně zabýval?

 
Odpovědět 1.11.2015 23:17
Avatar
Luboš
Člen
Avatar
Odpovídá na Luboš
Luboš:

Ještě dodávám: Jde o to, že klient je obvykle uživatel aplikace nikoliv její tvůrce.

 
Odpovědět 1.11.2015 23:24
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na Luboš
Milan Křepelka:

Asi nejsme na stejné vlně. Běžně pro SQL se datum příkazů zadává takt jak psal JOF. Nicméně tak jak to máš, tak to je stejně nedobře a takhle by se to dělat nemělo. Ten tvůj příkaz má vypadat takto

SELECT [NazevPolozky] FROM [Tabulka3] WHERE [Tabulka3].[Datum]=@MujDatumParam

a do commandu naplnit parametr, podobně jak je v 5.tém dílu a s tím, že do parametru nacpeš, že to je datum a nastavíš už typovou promennou DateTime, takže nějakým formátem ala "jak vlastně" vypadá datum vůbec nebudeš muset zabývat

 
Odpovědět 2.11.2015 6:25
Avatar
Petr Vocel
Redaktor
Avatar
Petr Vocel:

Musím upozornit na nesoulad mezi SQLConnection­StringBuilder a SqlConnection. První při vytváření obloží cestu k dat.file úvozovkami, což druhý nepředpokládá a zhavaruje. Alespoň ve verzi studia 2015. Jako důkaz přikládám program a výslednou obrazovku.

namespace SlovickaSQL
{
    class Program
    {

          static void Main(string[] args)
        {
            string pripojovaciRetezec2 = @"Data Source= (LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Uceni_SQL_MS-SQL\Database\SlovnicekDB.mdf; Integrated Security = True; Connect Timeout = 30";
            Console.WriteLine("Připojovací řetezec z vlastností\n {0}<<", pripojovaciRetezec2);
            using (SqlConnection pripojeni = new SqlConnection(pripojovaciRetezec2))
            {
                Console.WriteLine("Zkusím se připojit s tímto textem:\n={0}<<", pripojovaciRetezec2);
                pripojeni.Open();
                Console.WriteLine("Aplikace se úspěšně připojila k databázi.");
                pripojeni.Close();
                Console.WriteLine("Aplikace se úspěšně odpojila od databáze.");
            }
            // získání connect stringu <
            SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
            csb.DataSource = @"(LocalDB)\MSSQLLocalDB";
            csb.AttachDBFilename = @"C:\Uceni_SQL_MS - SQL\Database\SlovnicekDB.mdf";
            csb.IntegratedSecurity = true;
            string pripojovaciRetezec1 = csb.ConnectionString;
            Console.WriteLine("Připojovací řetezec sestavený \n {0}<<", pripojovaciRetezec1);
            using (SqlConnection pripojeni = new SqlConnection(pripojovaciRetezec1))
            {
                Console.WriteLine("Zkusím se připojit s tímto textem:\n={0}<<",pripojovaciRetezec1);
                pripojeni.Open();
                Console.WriteLine("Aplikace se úspěšně připojila k databázi.");
                pripojeni.Close();
                Console.WriteLine("Aplikace se úspěšně odpojila od databáze.");
            }
            Console.ReadKey();

        }
    }
}

Výsledná obrazovka
Připojovací řetezec z vlastností
Data Source= (LocalDB)\MSSQLLo­calDB;AttachDbFi­lename=C:\Uce­ni_SQL_MS-SQL\Database\Slov­nicekDB.mdf; Integrated Security = True; Connect Timeout = 30<<
Zkusím se připojit s tímto textem:
=Data Source= (LocalDB)\MSSQLLo­calDB;AttachDbFi­lename=C:\Uce­ni_SQL_MS-SQL\Database\Slov­nicekDB.mdf; Integrated Security = True; Connect Timeout = 30<<
Aplikace se úspěšně připojila k databázi.
Aplikace se úspěšně odpojila od databáze.
Připojovací řetezec sestavený
Data Source=(Local­DB)\MSSQLLocal­DB;AttachDbFi­lename="C:\Uce­ni_SQL_MS - SQL\Database\Slov­nicekDB.mdf";In­tegrated Security=True<<
Zkusím se připojit s tímto textem:
=Data Source=(Local­DB)\MSSQLLocal­DB;AttachDbFi­lename="C:\Uce­ni_SQL_MS - SQL\Database\Slov­nicekDB.mdf";In­tegrated Security=True<<

Hláška
An unhandled exception of type 'System.Data.SqlCli­ent.SqlExcepti­on' occurred in System.Data.dll

Additional information: An attempt to attach an auto-named database for file C:\Uceni_SQL_MS - SQL\Database\Slov­nicekDB.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.

 
Odpovědět 21.5.2016 11:54
Avatar
JOF
Tým ITnetwork
Avatar
Odpovídá na Petr Vocel
JOF:

Ahoj,

v druhém případě máš v cestě k souboru nějaké mezery navíc - "...Uceni_SQL_MS - SQL...".
Nebude to tím?

 
Odpovědět 22.5.2016 7:50
Avatar
Petr Vocel
Redaktor
Avatar
Odpovídá na JOF
Petr Vocel:

Ahoj,
máte pravdu. Nevím jak se mi tam dostaly, text jsem určitě odněkud kopíroval, ale po odstranění ve volacích parametrech pro bilder, je výsledek již bez úvozovek a vše prochází, tak jak má. Dík.
Petr

:-)
 
Odpovědět 22.5.2016 8:42
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 36. Zobrazit vše