Seriály Reklama
Vývojářské akce

Je WebMatrix a LightSwitch pro lamy?
5.10.2010 18:00 - 20:00, Praha - Microsoft

Další akce...

Spřízněné servery

Úvod do ADO.NET (1.)

Miloslav Beňo | Vydáno 21. září 2005 | Komentářů: 2 | Tutoriály

V první části trojdílného seriálu zabývajícím se základy ADO.NET se podíváme na jeho základní třídy a metody. Povíme si něco o poskytovatelích připojení, connection poolingu. Uvidíme pár praktický příkladů, mimo jiné, jak do databáze vkládat a vybírat binární data( např. obrázky).

Z Obsahu:

  • Poskytovatelé připojení
  • Navázání připojení
  • Otevírání a zavírání připojení
  • Connection Pooling.
  • Třídy příkazů
  • Vykonávání příkazů
  • SqlCommand.ExecuteNonQuery
  • SqlCommand.ExecuteScalar
  • SqlCommand.ExecuteReader

reklama

V první části trojdílného seriálu zabývajícím se základy ADO.NET se podíváme na jeho základní třídy a metody. Povíme si něco o poskytovatelích připojení, connection poolingu. Uvidíme pár praktický příkladů, mimo jiné, jak do databáze vkládat a vybírat binární data( např. obrázky).

Z Obsahu:

  • Poskytovatelé připojení
  • Navázání připojení
  • Otevírání a zavírání připojení
  • Connection Pooling
  • Třídy příkazů
  • Vykonávání příkazů
  • SqlCommand.ExecuteNonQuery
  • SqlCommand.ExecuteScalar
  • SqlCommand.ExecuteReader

Poskytovatelé připojení

Před jakoukoliv prací s databází je nutné se rozhodnout jakou databázi vlastně budete používat. Pokud chcete použít Microsoft SQL Server 7.0 nebo vyšší, použijte poskytovatele .NET SQL serveru. V zásadě platí pokud chcete použít jakoukoliv jinou databázi použijte poskytovatele .NET OLE DB( OLE DB je technologie pro přístup k datům používaná .NETem, je to podobné ODBC - Open Database Connectivity ). Tento poskytovatel je pomalejší než poskytovatel .NET SQL Serveru, který celou dobu běhu setrvává v řízeném kódu. Může se stát, že vámi používaná databáze nepůjde otevřít ani přes .NET OLE DB, pak je nutné někde získat funkčního poskytovatele pro tuto databázi nebo použít .NET ODBC společnosti Microsoft, tím se zde ale nebudeme zabývat.

Nás teď spíše zajímá jak s poskytovateli pracovat. Je to v podstatě jednoduché. Pokud používáte poskytovatele .NET SQL Serveru bude vás zajímat jmenný prostor System.Data.SqlClient a pro poskytovatele .NET OLE DB je to System.Data.OleDb. Je příjemné, že funkce v těchto jmenných prostorech se v zásadě lišší jen předponami, např. SqlConnectionOleDbConnection, SqlCommandOleDbCommand, SqlExceptionOleDbException… a některé další třídy používané pro prácí s daty fungují se všemi poskytovateli, např. DataSet,DataTable,…

Navázání připojení

Než na databázi vykonáte jakýkoliv příkaz je nutné otevřít spojení. K tomu slouží třída SqlConnection.

SqlConnection pripojeni = new SqlConnection("server=localhost;database=mojeDatabaze;uid=sa;pwd=");

Následující kód je ekvivalentní:

SqlConnection pripojeni = new SqlConnection();
Pripojeni.ConnectionString = "server=localhost;database="+
                             "mojeDatabaze;uid=sa;pwd=";

Parameter server specifikuje adresu MSSQL serveru, v tomto případě je to localhost. Database nám určuje jméno databáze na které chceme provádět příkazy. Uid se dá rovněž zapsat jako User Id, což specifikuje uživatelské jméno a pwd je ekvivalentní s Password, čili heslo.

Tyto parametry rozhodně nejsou jediné. Jejich úplný výčet naleznete v dokumentaci vlastnosti SqlConnection.ConnectionString.

Navázaní připojení přes poskytovatele .NET OLE DB je obdobné, pouze je zde nutné zahrnout parameter provider a nastavit ho na sqloledb pro SQL server nebo případně na msdaora pro Oracle.

OleDbConnection pripojeni = new OleDbConnection
   ("provider=sqloledb;server=localhost;database="+
    "mojeDatabaze;uid=sa;pwd=");

Otevírání a zavírání připojení

Ať už pro SqlConnection nebo pro OleDbConnection, chcete-li pracovat s databází, je nutné připojení otevřít.

Pripojeni.Open();

A následně také zavřít

Pripojeni.Close();

Jelikož operace vykonávané nad databází mohou vyvolat výjimky SqlException resp. OleDbException je velmi vhodné celou tuto režii uzavřít do bloku try.

SqlConnection prip = new SqlConnection("server=localhost;database=mojeDatabaze;uid=sa;pwd=");

try
{
   prip.Open();
   //Prikazy
}
catch(SqlException ex)
{
   //Osetreni vyjimky
}
finally
{
   prip.Close();
}

Uzavření připojení v bloku finally se provede vždy. To nám ale nepřekáží, protože uzavření spojení, které není otevřené, ničemu nevadí.

Connection Pooling

Vytvoření spojení se SQL serverem vyžaduje velkou režii a proto je velmi časově nákladné. Je nutné se připojit k serveru, provést autentikaci(ověření uživatele) a vrátit platné spojení. Kdyby se mělo toto všechno provádět při každém otevření stránky, tak by se výkon takovéto aplikace při silnější zátěži dal měřit kalendářem. Proto je zde pooling, který uchovává otevřená připojení v tzv. fondech. Tím tato režie odpadá.

Maximální a minimální počet připojení se dá nastavit v ConnectionString pomocí „min pool size“ a „max pool size“ (výchozí hodnoty jsou 0 a 100). Nastavením prvního z těchto parametrů na hodnotu větší než nula zajistíte předběžné naplnění fondu připojení zadaným počtem připojení. Zrychlíte tak rozjezd aplikace u které se předpokládá vyšší zatížení.

Takže je nutné na tuto vlastnost pamatovat a pokaždé když otevřete nové připojení ať už přes SqlConnection nebo OleDbConnection byste měli zase v nějaké rozumně krátké době připojení uzavřít. Ve skutečnosti se totiž připojení neuzavře, spíše se Ado.Net dozví, že toto připojení je volné a může ho použít zase něco jiného.

Třídy příkazů

Když chceme v .NET zavolat nějaký SQL příkaz používáme k tomu třídu SqlCommand, resp. OleDbCommand.

SqlCommand command = new SqlCommand("SELECT * FROM tabulka",prip);

Při vytvoření objektu command se nainicializuje jeho vlastnost CommandText a Connection z argumentů předaných konstruktoru.

Vykonávání příkazů

Nyní již máme příkaz vytvořen a je třeba ho vykonat. K tomu slouží 3 metody třídy SqlCommand: ExecuteNonQuery, ExecuteScalar a ExecuteReader. Podívejme se tedy na každou zvlášť.

Pro testovací účely si vytvořme databázi a do ní vložme jednu tabulku.

create database mojeDatabaze
go

use mojeDatabaze
go

create table zamestnanci
(
   id      int identity(1,1) not null,
   jmeno   varchar(30)       not null,
   pozice  varchar(30)       not null,
   adresa  varchar(50)       not null,
   telefon varchar(15)       not null,
   plat    money             not null,
   foto    image
)

SqlCommand.ExecuteNonQuery

Tato metoda slouží k vykonávání SQL příkazů od kterých nepožadujeme výstup. Jedná se o SQL příkazy jako INSERT,UPDATE,DELETE, CREATE DATABASE,CREATE TABLE, DROP TABLE,… Návratová hodnota je -1 pro všechny SQL příkazy kromě INSERT,UPDATE, DELETE. U těchto příkazů se nám vrátí počet řádků ovlivněných jejich vykonáním.

V následujícím příkladu přidáváme do tabulky zaměstnanců nového zaměstnance včetně jeho fotografie.

SqlConnection prip = newSqlConnection("server=localhost;database=mojeDatabaze;uid=sa;pwd=");

// Následující řádky nainicializují pole blob obrázkem načteným ze
// souboru foto.jpg
FileStream proud = new FileStream("foto.jpg",FileMode.Open);
byte[] blob = new byte[proud.Length];
proud.Read(blob,0,(int)proud.Length);

try
{
   prip.Open();
   SqlCommand prikaz = new SqlCommand
      ("INSERT INTO zamestnanci"+
       "(jmeno, pozice, adresa, telefon, plat, foto)"+
       "VALUES('Petr Ryba', 'poskok', 'Jemenska 17',"+
       "'555585', 12000, @foto)",prip);
   prikaz.Parameters.Add("@foto",blob);
   int i =prikaz.ExecuteNonQuery();

}
catch(SqlException ex)
{
   //Osetreni vyjimky
}
finally
{
   prip.Close();
}

Tento příklad nejen vkládá nový řadek s informacemi o zaměstnanci, ale rovněž do databáze zapisuje objekt BLOB( binary large object – binární velký soubor). V tomto konkrétním případě se jedná o obrázek, ale samozřejmě to může být cokoliv.  Používají se k tomu tzv. parametrizované příkazy, o nich si však povíme v dalším díle.

SqlCommand.ExecuteScalar

Tato metoda vrací první sloupec v prvním řádku, který vrátí SQL příkaz vykonaný touto metodou. Proto se používá hlavně pro SQL příkazy typu COUNT,MIN,MAX,AVG,SUM. Další častý způsob použití je získávání objektů BLOB. Podívejme se tedy na příklad, který činí právě toto.

public Bitmap GetFoto(int id)
{
   SqlConnection prip = new SqlConnection
      ("server=localhost;database=mojeDatabaze;uid=sa;pwd=");
   MemoryStream proud = new MemoryStream();
   Bitmap foto = null;    

   try
  
{
      prip.Open();
      SqlCommand prikaz = new SqlCommand
         ("SELECT foto FROM zamestnanci WHERE id=@id",prip);
      prikaz.Parameters.Add("@id",id);
      byte[] blob = (byte[])prikaz.ExecuteScalar();
      proud.Write(blob,0,blob.Length);
      foto = new Bitmap(proud);
   }
   catch(SqlException ex)
   {
      //Osetreni vyjimky
   
}
   finally
  
{
      prip.Close();
   }   
 
  return foto;   
}

Tato metoda vrací instanci třídy Bitmap obsahující fotografii z tabulky zamestnanci podle argumentu id. Vytvoří se zde příslušný SQLCommand s parametrem id(co to přesně je se dovíte príště) a zavolá se metoda ExecuteScalar(), která vrátí binární data obrázku. Ty je nutné přetypovat na byte[], protože ExecuteScalar kvůli obecnosti vrací Object. Následně toto pole bytů zapíšeme do paměťového proudu MemoryStream, který pak předáme konstruktoru třídy Bitmap.

Dalším častým použitím metody ExecuteScalar je autentikace uživatele, jak uvidíte v příštím díle.

SqlCommand.ExecuteReader

Tato metoda vrací objekt SqlDataReader, resp. OleDbDataReader pokud je zavolána na objektu OleDbCommand.  Tento objekt se následně používá pro iterování výsledkem dotazu vykonaného na databázi. Je necachovaný, dopředný a pouze pro čtení. Je však velmi efektivní, přejímá pouze ty data, která chcete. I když bude výsledek SQL dotazu obrovský a vy si přečtete pouze pár záznamů, skutečně se jich přečte jen pár.

SqlConnection prip = new SqlConnection
   ("server=localhost;database=mojeDatabaze;uid=sa;pwd= ");

try
{
   prip.Open();
   SqlCommand prikaz = new SqlCommand
      ("SELECT jmeno FROM zamestnanci",prip);
    
   SqlDataReader ctenar = prikaz.ExecuteReader();    

   while
(ctenar.Read())
      Console.WriteLine(ctenar["jmeno"]);             
}
catch(SqlException ex)
{
    //Osetreni vyjimky
}
finally
{
   prip.Close();
}

Každé volání metody Read načte jeden řádek z množiny výsledků. Pro přístup k položkám tohoto řádku můžete využít indexer tohoto objektu. Jako index lze použít jméno sloupečku nebo jeho index ( zde by to bylo ctenar[0] ).

Pokud používáte DataReader, nemůžete na tomto spojení vykonat žádnou jinou operaci. To platí dokud objekt DataReader nezavřete voláním metody Close. Tuto metodu nemusíte volat, pokud nemáte v úmyslu na tomto spojení žádné další operace vykonávat, ale samozřejmě se to doporučuje.

Objekt DataReader obsahuje i další zajímavé metody, jako například GetSchemaTable, která vrací objekt DataTable z něhož lze získat strukturu výsledku. Nebo pokud chcete například zjistit název určitého sloupečku o určitém indexu, zavolejte GetName. Třída má metod samozřejmě mnohem více, pro bližší informace nahlédněte do dokumentace této třídy v msdn.

Užitečné odkazy

Řetězce připojení pro nejrůznější existující databáze - www.connectionstrings.com

V režimu TEXT nejsou povoleny žádné HTML značky. Odstavce jsou vytvořeny automaticky, webové adresy a e-maily jsou převedeny na odkazy. V režimu "HTML" jsou povoleny následující elementy: a b i cite strong em p br code blockquote ul ol li. Redakce si vyhrazuje právo komentáře mazat.








2 komentářů | řadit podle tématu

RE: Kam vkládat tento kód?

Reakce na Kam vkláda… Kocour 6. února 2010 82.150.166.×××

no jelikoz sou vsechny zdrojaky v C#, tak do projektu visual basicu urcite ne... Kam presne to pak vlozis, zalezi na strukture programu, takze na tobe. Jestli se jedna o nakou windows aplikaci, tak nejspis do obsluhy udalosti (klik tlacitka apod.), v pripade console to hod treba do mainu, nebo si vytvor tridu, pouzij ty zdroje jako implementaci naky metody a pak ji z mainu volej, atd atd. Moznosti je spousta, zalezi na tobe, kdy se chces pripojit k databazi, kdy chces manipulovat nejakym zpusobem s daty atd. Nijak konkretne ti na tento obecny dotaz nemuzu odpovedet...

Kam vkládat tento kód?

Mike 21. srpna 2007 85.207.39.×××

Ahoj... super vysvětlení akorát netuším kam vkládat tento kód .. do projektu Microsoft Aplikace VB.net? nebo do nějakého Class? poraďte prosím děkuju

Uživatel

Pro zobrazení informací o svém účtu se musíte přihlásit. Pokud ještě nemáte svůj účet, tak si ho prosím vytvořte!

Reklama
Odběr článků

Pokud se přihlásíte k odběru zpráv, pošle Vám systém každý týden e-mail se seznamem posledních článků.

Zdrojak .NET Hosting Reklama
 
  Copyright 2002-2007 Devmasters s.r.o., Michal Bláha a autoři | running on Nemesis Publishing | Právní doložka  
TOPlist