Baza danych
Transkrypt
Baza danych
Praca z bazą danych Aby móc korzystać z niniejszego kursu musimy utworzyć bazę danych o nazwie KURSY, tabelę o nazwie UZYTKOWNIK, a w tabeli tej utworzyć następujące kolumny: user_id typu integer/autonumer not null imie typu znakowego o rozmiarze 50 znaków nazwisko typu znakowego o rozmiarze 50 znaków zdjecie typu image/blob/Obiektowe Typ danych jest oczywiście zaleŜny od uŜytego serwera, dla MS SQL Serwera definicja bazy, tabeli i kolumn przedstawia się jak poniŜej: Rysunek 1. Projekt tabeli UZYTKOWNIK bazy KURSY W przypadku serwerów MS SQL lub MySQL dodajmy jeszcze uŜytkownika (w tym przykładzie dodany jest uŜytkownik i login „tech”), a w przypadku MS SQL równieŜ login tak abyśmy przez tego uŜytkownika mogli łączyć się z bazą danych (szczegóły odnośnie dodawania uŜytkowników w poszczególnych serwerach baz danych proszę doczytać w dokumentacji / literaturze lub w necie). Pragnę tutaj zwrócić uwagę na definicję kolumny „user_id”, która jest kolumną „autoinkrementowaną”, czyli numerowaną automatycznie przez system bazy danych. Jeszcze tak pro forma typów danych to w przypadku MySQL będą to odpowiednio typy: BIGINT(20) z opcją „autoincrement”, VARCHAR(50) i BLOB, a w przypadku Access będą to typy: Autonumer, Tekst(50) i Obiekt Ole. JeŜeli utworzyliśmy juŜ bazę, tabelę i kolumny to teraz trochę teorii na temat łączenia z bazą danych. OtóŜ, aby połączyć się z bazą danych musi być tzw. dostawca, który dostarcza specjalizowane narzędzia do połączenia się z daną bazą danych. Standardowo środowisko Framework .NET zawiera między innymi dostawców umoŜliwiających łączenie się z MS SQL Serwer (SQLClient), bazą Access (OleDb i ODBC). Dostawca SQLClient jest specjalizowany do połączeń z bazą MS SQL Serwer, natomiast dostawcy OleDb i ODBC są bardziej uniwersalni i pozwalają łączyć się z innymi bazami danych obsługujących / posiadających dany sterownik. W przypadku MySQL najlepiej jest pobrać i zainstalować specjalizowanego dostawcę (MySQLClient) dostępnego na stronie domowej MySQL. Dany sterownik / dostawca zawiera między innymi klasę / obiekt „Connection”, która za pomocą właściwości „ConnectionString” łączy się z bazą danych. Tak więc ośmielę się stwierdzić, Ŝe właściwość „ConnectionString” obiektu „Connection” jest kluczowym elementem w pracy z bazą danych (bo bez niego i jego prawidłowej postaci nic nie będzie działało, a więc poprawne konstrukcje zapytań SQL – tak jak i niepoprawne ☺ - nie zadziałają). A skoro tak to teraz omówimy trochę dokładniej tę właściwość. JeŜeli uŜyjemy „Wizzarda” połączeń do źródeł danych z Visual Studio to utworzona właściwość „ConnectionString” dla serwera MS SQL będzie miała przykładową postać: Data Source=.\SQLEXPRESS;AttachDbFilename="C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\KURSY.mdf";Persist Security Info=True;User ID=tech;Connect Timeout=30;User Instance=True a dla bazy Access będzie miała przykładową postać: Provider=Microsoft.Jet.OLEDB.4.0;Data Source="C:\Documents and Settings\wicio\Moje dokumenty\Moje kursy\Kursy.mdb" Jak juŜ pobieŜnie widać, Ŝe pomimo pewnych podobieństw „stringi” te są róŜne dla róŜnych systemów bazodanowych i prawidłowa definicja tych ciągów jest sporym wyzwaniem nawet dla bardziej doświadczonych programistów. PoniŜej przedstawiam zatem najprostszą konstrukcję działających „ConnectionString” dla baz danych MS SQL Serwer, Access i MySQL: MS SQL Serwer – postać ogólna „ConnectionString”: „server=<nazwa_serwera_lub_jego_IP>\<nazwa_instancji_serwera_SQL>,<port>;us er id=<uŜytkownik>;password=<hasło>;database=<nazwa_bazy_danych>” gdzie: <nazwa_serwera_lub_jego_IP> to nazwa komputera (lub numer IP tego komputera), na którym zainstalowany jest SQL Serwer (jeŜeli serwer SQL jest zainstalowany na komputerze, na którym będziemy uruchamiali program to moŜna uŜyć nazwy „localhost”) <nazwa_instancji_serwera_SQL> to nazwa instancji, do której chcemy się podłączyć. Serwer SQL moŜe mieć wiele róŜnych instancji; dla standardowej instalacji będzie to nazwa „SQLEXPRESS” <port> to numer portu, na którym „słucha” serwer SQL; standardowo jest to port 1433 <uŜytkownik> to nazwa uŜytkownika posiadającego uprawnienia do bazy danych na serwerze SQL <hasło> to hasło tego uŜytkownika <nazwa_bazy_danych> to nazwa bazy, do której chcemy się podłączyć; kaŜda instancja serwera moŜe zawierać wiele baz danych Przykładowa postać tego łańcucha dla MS SQL Serwera: „server=localhost\SQLEXPRESS;user id=tech;password=tech;database=KURSY” Access – postać ogólna “ConnectionString”: “provider=<nazwa_prowidera>;Data Source=<ścieŜka_z_nazwą_pliku_mdb>” gdzie: <nazwa_prowidera> to nazwa dostawcy usług połączeniowych < ścieŜka_z_nazwą_pliku_mdb> to nazwa pliku z bazą danych wraz z rozszerzeniem i pełną ścieŜką dostępu Przykładowa postać tego łańcucha dla bazy Access: conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\Documents and Settings\wicio\Moje dokumenty\Moje kursy\kursy.mdb" NaleŜy tutaj zaznaczyć, Ŝe dla połączenia z bazą Access musimy w tym wypadku mieć zainstalowane oprogramowanie MS Jet, które jest standardowo instalowane w przypadku posiadania oprogramowania Office Access. JeŜeli nie mamy zainstalowanego oprogramowania Office Access, a tylko korzystamy z pliku bazy w tym formacie to moŜemy nie mieć zainstalowanego oprogramowania MS Jet i wówczas trzeba je zainstalować. MySQL – postać ogólna „ConnectionString” „serwer=<nazwa_serwera_lub_jego_IP>;user id=<uŜytkownik>;password=<hasło>;database=<nazwa_bazy> gdzie: <nazwa_serwera_lub_jego_IP> to nazwa serwera (lub numer IP), na którym zainstalowany jest serwer MySQL <uŜytkownik> to identyfikator uŜytkownika z uprawnieniami do danej bazy <hasło> to hasło tego uŜytkownika <nazwa_bazy> to nazwa bazy danych, do której chcemy się podłączyć Przykładowa postać tego łańcucha dla MySQL: „serwer=localhost;user id=admin;password=admin;database=kursy” Oczywiście załoŜeniem jest, Ŝe zainstalowany jest odpowiedni dostawca dla MySQL (MySQLClient). To byłoby tyle teorii, a teraz jeszcze zanim przejdziemy do praktyki wprowadźmy do utworzonej tabeli przynajmniej jeden rekord z danymi „imie” i „nazwisko” – pole „zdjecie” zostawiamy sobie na następny kurs. Wprowadzenie danych moŜna przeprowadzić za pomocą „managera” – dla MS SQL to „SQL Server Management Studio Express” dostępny na stronach Microsoftu, dla Access to oczywiście Office Access, a dla MySQL to np. „MySQL Administrator” dostępny ySQL. No to teraz przechodzimy do praktyki. Dokonamy teraz połączenia z bazą, pobrania danych z tabeli UZYTKOWNIK i wyświetlenia tych danych (załóŜmy teoretycznie, Ŝe będą to dane zalogowanego uŜytkownika do bazy – teoretycznie, bo nie mamy tu procedury logowania do bazy). Pobrane dane wyświetlimy w pasku stanu okna głównego aplikacji. Na początek zaimportujemy odpowiednią „przestrzeń nazw” zawierającą obiekty odpowiedniego providera. Dla MS SQL będzie to polecenie: Imports System.Data.SqlClient, dla bazy Acces będzie to polecenie: Imports System.Data.OleDb, a dla bazy MySQL będzie to polecenie: Imports Mysql.Data.MySqlClient. Przy czym dla MySQL musimy najpierw dodać „referencje” do projektu jak poniŜej (oczywiście przy załoŜeniu, Ŝe zainstalowaliśmy dostawcę dla MySQL): Rysunek 2. Dodawanie referencji do projektu dla MySQL Aby dodać te referencje musimy na zakładce „Solution Explorer” zaznaczyć nazwę projektu i wybrać przycisk „Properties”: Rysunek 3. Wywołanie okna właściwości projektu dla dodania referencji Polecenie „Imports…” umieszczamy na początku kodu przed linią deklarującą klasę: Public Class Glowne. Do pobrania danych uŜyjemy obiektów „Connection”, „Command” i „DataAdapter” właściwych dla danego dostawcy oraz ogólnego obiektu „DataSet”. W związku z powyŜszym musimy w procedurze „Load” okna głównego umieścić następujące deklaracje zmiennych: Dim Dim Dim Dim dc As SqlClient.SqlConnection da As SqlClient.SqlDataAdapter cmd As SqlClient.SqlCommand ds As New DataSet Dim konstr As String Dim komenda As String Oczywiście nazwy dc, da, ds mogą być dowolnie inne, natomiast pod zmienną konstr będziemy przechowywali nasz „ConnectionString”, a pod zmienną komenda będziemy przechowywali komendę SQL. Dalej w kodzie programu inicjujemy te zmienne i definiujemy „ConnectionString”: konstr = "serwer=localhost\SQLEXPRESS;user id=tech;password=tech;database=KURSY" dc = New SqlClient.SqlConnection(konstr) If dc.State <> ConnectionState.Open Then dc.Open() End If da = New SqlClient.SqlDataAdapter() cmd = New SqlClient.SqlCommand Zmienna konstr powinna być zapisana w jednej linii lub, jeŜeli chcemy zapisać w kilku to powinniśmy „powiedzieć” to kompilatorowi poprzez zapis w następującej postaci: konstr = "serwer=localhost\SQLEXPRESS;" & _ "user id=tech;password=tech;database=KURSY" gdzie znak & oznacza łączenie dwóch ciągów w jeden, a znak “_” oznacza informację dla kompilatora, Ŝe zapis w linii następnej jest kontynuacją linii bieŜącej. Część kodu zawarta w instrukcji „If” sprawdza czy połączenie z bazą jest otwarte i jeŜeli nie to je otwiera. Po inicjacji zmiennych konstruujemy zapytanie SQL do bazy i poniewaŜ będzie to instrukcja „Select” to definiujemy właściwości „CommandText” i „Connection” obiektu „SqlCommand”, wiąŜemy obiekt „Command” z obiektem „DataAdapter” poprzez ustawienie właściwości „SelectCommand” jako, Ŝe polecenie SQL jest typu „Select” oraz komendę SQL: komenda = "SELECT * FROM UZYTKOWNIK" cmd.CommandText = komenda cmd.Connection = dc da.SelectCommand = cmd i na koniec pozostaje nam odczyt danych z bazy: Try da.Fill(ds, "uzyt") Catch ex As Exception MessageBox.Show(ex.Message, "BŁĄD !!!", MessageBoxButtons.OK, _ MessageBoxIcon.Error, MessageBoxDefaultButton.Button1) End Try PowyŜsza konstrukcja to tzw. przechwytywanie i obsługa błędów i w skrócie polega na tym, Ŝe pomiędzy słowami „Try Catch…” umieszczamy instrukcje, które stanowią potencjalne źródło błędów (polecenia odczytujące dane z bazy mogą generować błędy na skutek np. braku dostępu do bazy z róŜnych przczyn), a pomiędzy „Catch… End Try” umieszczamy kod wykonywany w sytuacji gdy instrukcja wywołała błąd. W naszym przykładzie jako obsługę błędu po prostu wyświetlamy komunikat z treścią błędu w okienku z tytułem „BŁĄD !!!”, jednym przyciskiem „OK.” i ikonką błędu w oknie tego komunikatu. JeŜeli chodzi natomiast o komendę: da.Fill(ds., „uzyt”) to komenda ta powoduje odczyt danych z bazy i zapisanie ich do zmiennej ds – będącej obiektem DataSet w tablicy o nazwie „uzyt”. Obiekt „DataSet” jest jak gdyby bazą danych mogącą zawierać wiele róŜnych tablic (kaŜda moŜe mieć inną strukturę) z zawartością wstawioną poprzez odczyt z bazy lub programowo. Mamy juŜ odczytane dane (o ile oczywiście zostały do bazy wprowadzone – tabela „UZYTKOWNIK” zawiera jakieś rekordy danych) więc teraz trzeba by je wyświetlić w pasku stanu. PoniewaŜ pasek stanu zawiera trzy elementy składowe to w jednym umieścimy dane odczytane z bazy, w drugim umieścimy nazwę komputera, a w trzecim nazwę uŜytkownika zalogowanego w systemie Windows. Dane odczytane z bazy mamy w zmiennej ds typu DataSet natomiast pozostałe wartości: nazwę komputera i nazwę uŜytkownika Windows odczytamy ze zmiennych środowiskowych: najpierw zmieniamy nieco definicje zmiennych: Dim komenda, komputer, userwind As String i dopisujemy linie: komputer = System.Environment.MachineName userwind = System.Environment.UserName oraz linie: Me.tsl_kom1.Width = Math.Round(Me.StatusStrip1.Width / 3, 0) Me.tsl_kom2.Width = Math.Round(Me.StatusStrip1.Width / 3, 0) Me.tsl_kom1.Text = "Dane z bazy: " If ds.Tables("uzyt").Rows.Count > 0 Then Me.tsl_kom1.Text = Me.tsl_kom1.Text & _ CStr(ds.Tables("uzyt").Rows(0).Item("nazwisko")) & " " & _ CStr(ds.Tables("uzyt").Rows(0).Item("imie")) End If Me.tsl_kom2.Text = "Nazwa komputera: " & komputer Me.tsl_kom3.Text = "UŜytkownik Windows: " & userwind Pierwsze dwie linie powodują ustawienie długości kaŜdego z dwóch pierwszych elementów paska stanu na 1/3 długości całego paska stanu. Linia trzecia podstawia stały tekst do pierwszego elementu, dalej sprawdzamy czy istnieją jakieś dane odczytane z bazy (to znaczy czy tabela „usyt” obiektu DataSet zawiera chociaŜ jeden rekord) i jeŜeli tak to dopisuje do tekstu (znak „&” oznacza dodawanie tekstu) dane z bazy – czyli wartość kolumny „nazwisko” plus znak spacji plus wartość kolumny „imie” (naleŜałoby tutaj sprawdzić jeszcze czy kolumny te nie zawierają przypadkiem wartości NULL ale tym zajmiemy się w kolejnych kursach – zakładamy chwilowo, Ŝe kolumny te zawierają wartości róŜne od NULL). Ostatnie dwie linie to podstawienie odpowiedniego tekstu do kolejnych dwóch elementów paska stanu. Przed zapisem i uruchomieniem programu przejdźmy jeszcze do zakładki „Properties” dla obiektu „StatusStrip”, otwórzmy okno dla właściwości „Items” (Collection) i ustawmy właściwości dla kaŜdego z elementów: „BorderSides na „All”, „BorderStyle” na „Sunken”, „DisplayStyle” na „Text” oraz dla dwóch pierwszych „AutoSize na „False”, a dla ostatniego „Spring” na „True”. Właściwość „AutoSize” dla dwóch pierwszych ustawiamy na „False” z tej przyczyny, Ŝe ich długość będziemy ustawiali programowo, czyli ich wymiary nie mogą być ustawiane automatycznie, a dla trzeciego właściwość „Spring” ustawiamy na „True” aby ten ostatni wypełnił sobą całą pozostałą przestrzeń (po ustawieniu długości dwóch pierwszych elementów) obiektu „StatusStrip”. PoniŜszy rysunek prezentuje istotne ustawienia właściwości dwóch pierwszych elementów: Rysunek 4. Właściwości elementów obiektu StatusStrip Po wprowadzeniu tych zmian zapisujemy i uruchamiamy projekt, w wyniku czego powinniśmy uzyskać poniŜszy efekt: Rysunek 5. Okno główne aplikacji Cały kod aplikacji powinien wyglądać jak poniŜej: Imports System.Data.SqlClient Public Class Glowne Private Sub Glowne_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim wys, szer As Integer Dim dc As SqlClient.SqlConnection Dim da As SqlClient.SqlDataAdapter Dim cmd As SqlClient.SqlCommand Dim ds As New DataSet Dim konstr As String Dim komenda, komputer, userwind As String wys = Screen.PrimaryScreen.WorkingArea.Height szer = Screen.PrimaryScreen.WorkingArea.Width Me.Height = wys Me.Width = szer konstr = "server=localhost\SQLEXPRESS;" & _ "user id=tech;password=tech;database=KURSY" dc = New SqlClient.SqlConnection(konstr) If dc.State <> ConnectionState.Open Then dc.Open() End If da = New SqlClient.SqlDataAdapter() cmd = New SqlClient.SqlCommand komenda = "SELECT * FROM UZYTKOWNIK" cmd.CommandText = komenda cmd.Connection = dc da.SelectCommand = cmd Try da.Fill(ds, "uzyt") Catch ex As Exception MessageBox.Show(ex.Message, "BŁĄD !!!", MessageBoxButtons.OK, _ MessageBoxIcon.Error, MessageBoxDefaultButton.Button1) End Try komputer = System.Environment.MachineName userwind = System.Environment.UserName Me.tsl_kom1.Width = Math.Round(Me.StatusStrip1.Width / 3, 0) Me.tsl_kom2.Width = Math.Round(Me.StatusStrip1.Width / 3, 0) Me.tsl_kom1.Text = "Dane z bazy: " If ds.Tables("uzyt").Rows.Count > 0 Then Me.tsl_kom1.Text = Me.tsl_kom1.Text & _ CStr(ds.Tables("uzyt").Rows(0).Item("nazwisko")) & " " & _ CStr(ds.Tables("uzyt").Rows(0).Item("imie")) End If Me.tsl_kom2.Text = "Nazwa komputera: " & komputer Me.tsl_kom3.Text = "UŜytkownik Windows: " & userwind End Sub Private Sub mi_Koniec_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mi_Koniec.Click Application.Exit() End Sub Private Sub tsi_koniec_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles tsi_koniec.Click Me.Close() End Sub End Class To byłoby tyle w tym kursie. Powinniśmy teraz umieć połączyć się z bazą i pozyskać z niej dane jak równieŜ poznaliśmy niektóre komponenty i ich właściwości. W następnym kursie zajmiemy się obsługą danych z tabeli UZYTKOWNIK, a więc wyświetlanie danych, modyfikowanie, dodawanie i usuwanie tych danych ze szczególnym uwzględnieniem zapisu obrazów do bazy i ich wyświetlaniem w programie.