Poniżej zamieszczam krótki i jak najprostsze przykłady na to jak w róznych językach programowania zrealizować połączenie do bazy danych
W przykładach uzyjemy bazy danych MSSQL Server Express Edition, którą w wersji 2008 można ściągnąć stąd: MSSQL Server. Najlepiej ściągnąć wersję WT (With Tools), dzięki czemu będziemy mieli dostęp do Managment Studio.
Po zainstalowaniu wyonujemy następujący skrypt, mając uprawnienia admina. Z jakiś względów w Windows 7 (nie wiem jak w XP i Viscie) może pojawić się problem, że będziemy mieli uprawnienia dbo (database owner), tylko jesli uruchomimy Managment Studio jako admin (prawym klawisze, uruchom jao administrator). Można to obejść, stosując rozwiązanie stąd: Blog MSDN, Dariusz Parys. Jakkolwiek sobie ztym nie poradzimy należy wykonać następujący kod:
create database test go use test go create table t1( id INT PRIMARY KEY IDENTITY, nazwa VARCHAR(256), ilosc INT ) go create procedure sp_add_to_t1(@nazwa VARCHAR(256), @ilosc INT, @lastId smallint OUTPUT) as begin tran insert into t1(nazwa, ilosc) values(@nazwa, @ilosc) select @lastId = max(id) from t1 commit go declare @lastId INT EXEC sp_add_to_t1 'Blabla', 10, @lastId OUTPUT print @lastId EXEC sp_add_to_t1 'Nabla', 20, @lastId OUTPUT print @lastId
Poniżej znajdują się przykłądy dla różnych języków (PHP, Java, C#, Python). Serdecznie przepraszam, jesli Państwa ulubionego języka na liście nie będzie. Jesli ktoś chciałby aby takowy się pojawił, zachęcam do przeprowadzenia poszukiwan w sieci i stworzenia podobnego poradnika - z chęcią umieściłbym go na stronie za zgodą autora.
Aby móc testować aplikacje napisane w PHP możemy zainstalować serwer Apache, bardzo prostym i szybkim sposobem na testowanie jest XAMPP dla Windows lub LAMPP dla linux, które można pobrać stąd: XAMPP Home Page (Użytkownicy linux mogą użyć do instalacji narzedzi typu apt, aptitude, itp) Razem z xampp otrzymujemy bazę danych mysql, której także można uzyć w projekcie, chociaż ze względu na to że omawialiśmy głównie MSSQL Server i to że ten ostatni wspiera trochę lepiej procedury składowane i triggery to do projektu polecałbym to rozwiązanie.
Lista obsługiwanych baz wraz z listami funkcji PHP:
http://www.php.net/manual/en/refs.database.vendors.php
lista funkcji związanych z MySQL Server w PHP:
http://www.php.net/manual/en/ref.mysql.php
Jeśli ktoś nie zetknął się nigdy z PHP warto poczytać do czego on służy:
http://pl.wikipedia.org/wiki/PHP
i pomyśleć o przeczytaniu jakiegoś tutorialu:
PHP na w3schools
Po zainstalowaniu xampp, sprawdzamy czy działa. Należy uruchomić apache'a: z katalogu w którym zainstalowaliśmy xampp należy uruchomić (windows) apache_start.bat lub z paska narzędzi ikonka httpd. W linuxie powinien zainstalowac się jako proces i biec w tle, ale jesli trzeba można go uruchomić httpd -k start (najlepiej poczytać man httpd).
Wchodzimy do katalogu (katalog instalacyjny xampp, w skrócie dalej nazwany XAMPP_HOME)/htdocs, tworzymy nowy katalog np. o nazwie test a w nim plik o nazwie index.php (możemy stworzyć plik o innej nazwie np. test.php ale wtedy inaczej odniesiemy się do naszego pliku w przeglądarce). Edytujemy plik i wpisujemy kod:
<? echo ("Hello world!"); ?>Uruchamiamy przeglądarkę i wpisujemy: localhost/test (localhost/test/test.php jeśli nadaliśmy plikowi nazwę test zamiast index). Powinno w przeglądarce pojawić się hello world!.
Aby mozna się było łaczyć z bazą MS SQL potrzebujemy sterownika. Niestety domyślny sterownik nie jest wspierany od wersji PHP 5, więc musimy skorzystać z czegoś innego.
Pobieramy Microsoft Drivers for PHP for SQL Server. Instalujemy, wybierając podczas instalacji miejsce folderu rozszerzeń PHP. Domyślnym miejcem jest (XAMPP_HOME)/php/ext, tak więc ten katalog wybieramy. Po zainstalowaniu przechodzimy do tego katalogu - znajdziemy w nim plik pomocy SQLSRV_Help.chm - bardzo przydatny przy pracy z tym sterownikiem.
Ostatnią rzeczą jaką musimy zrobić, to zmodyfikować plik php.ini w katalogu (XAMPP_HOME)/php. Nalezy w nim znaleźć miejsce w którym jest wiele wpisów postaci extension=nazwa_pliku.dll. Najlepiej na samym dole listy dodać jeszcze jeden wpis: extension=php_sqlsrv_53_ts_vc9.dll (numerki w nazwie pliku oznaczają wersje PHP - dla XAMPPa działa wpis który podałem, dla własnych instalacji - może trzeba będzie wybrać inny)
Restartujemy Apache'a z paska zadań można włączyć ikonkę HTTPD i kliknąc stop a nastpnie start (z linii komend to pewnie httpd -k restart).
Teraz już możemy nawiązać połączenie z bazą danych, pobierać dane i wyświetlać w tabelce na stronie (podmień kod w pliku index.php):
<!-- początek pliku index.php --> <? //nazwa komputera\nazwa instancji //(domyslna nazwa instancji = SQLEXPRESS) $server = 'MACHINAZAGLADY4\SQLEXPRESS'; //$server = '(local)'; //user dodany tak jak robiliśmy to na pierwszych zajęciach //(w zakładce Security\Logins w Management Studio) $user = 'test'; //hasło do powyższego konta $pass = 'tajnehaslo'; $connectionInfo = array( "UID"=>$user, "PWD"=>$pass, "Database"=>"test"); // Connect to MSSQL $link = sqlsrv_connect( $server, $connectionInfo); if (!$link) { //die(komunikat) - zakończ skrypt z komunikatem die('Nie udało się połączyć'); } ?> <html> <head> <title>PHP + MS SQL</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> Można mieszać PHP z html. Tam gdzie chcemy wywołać kod PHP umiesczamy znaczniki <? i ?> a wewnątrz nich kod PHP. <table> <tr><th>Id</th><th>Nazwa</th><th>Ilość</th></tr> <? //kod php może być podzielony na kilka bloków - wszystkie zmienne //które zadeklarowaliśmy wczesniej i wszystkie operacje //które wykonaliśmy nadal są aktywne // wybierz wszystko z tabeli t1 $dataset = sqlsrv_query($link, 'SELECT * FROM t1'); $row = sqlsrv_fetch_array($dataset); while($row){ echo ("<tr><td>{$row[0]}</td><td>{$row[1]}</td><td>{$row[2]}</td></tr>"); $row = sqlsrv_fetch_array($dataset); } //warto posprzątać po sobie sqlsrv_free_stmt($dataset); ?> </table> Poniżej wyświetlamy formularz wstawiania nowych danych, formularz pozwala wyslac dane do serwera Apache, przekazując dane w postaci par klucz-wartość: kluczem jest to co wpiszemy w atrybucie 'name' danego pola, a wartoscią będzie to co użytkownik wpisze w to pole. Formularz może mieć określoną akcję - stronę (skrypt PHP) który zostanie wywołany oraz method, oznaczający sposób wysłania danych. Dostępne są dwa sposoby wysłania danych: POST i GET.<br/> <form action = "index.php" method = "POST"> Nazwa: <input type = "text" name = "pole_nazwa"/> <br/> Ilość: <input type = "text" name = "pole_ilosc"/><br/> <input type = "submit" value = "dodaj"> </form> <? //a tu kod obsługujący. Tak naprawdę powinien być //na samej górze strony, ale ze względów dydaktycznych //umieściłem go na dole. Z tego powodu wstawiony wiersz //będzie widoczny w tabeli dopiero po odświeżeniu strony. //dane podane przez uzytkownika wyciagamy z tabeli request //podajac nazwy pól z formularza $nowy_nazwa = $_REQUEST['pole_nazwa']; $nowy_ilosc = $_REQUEST['pole_ilosc']; //sprawdzamy czy user podał dane if ($nowy_nazwa && $nowy_ilosc){ //tak można wykonać procedurę składowaną z paramtrami //zwrócić uwagę nalezy na ? zamiast nazw parametrów $tsql = "{call sp_add_to_t1(?, ?, ?)}"; //zdefinuj nową zmienną na parametr zwracający dane $lastId = 4; //trzeba zainicjalizować go na wartośc typu jaki ma być zwrócony. //Uwaga: Nie wolno na null, albo pozostawiać niezainicjalizowanego //ustal parametry jako tablicę dwuelementowych tablic $params = array( array($nowy_nazwa, SQLSRV_PARAM_IN), //standardowy parametr array($nowy_ilosc, SQLSRV_PARAM_IN), //standardowy parametr array($lastId, SQLSRV_PARAM_OUT), //ten będzie parametrem OUT ); //wykonaj zapytanie $result = sqlsrv_query($link, $tsql, $params); if (!$result){ //tak można wypisać błędy które się pojawiły die( print_r( sqlsrv_errors(), true)); } //ta linijka jest potrzebna, aby pozbyć się //wszlekich zalegających danych, tylko tak pojawi //się wartośc parametru OUT while(sqlsrv_next_result($result)){}; //wyświetl info echo ('Dodano wiersz o id = ' . $lastId); } ?> </body> </html> <? // na koniec warto zamknąc połączenie sqlsrv_close( $link); ?> <!-- koniec pliku index.php -->
O formatkach w HTML mozna poczytać np. tutaj (w3schools). Teraz możemy zacząć budować naszą własną aplikację internetową!
ABy skorzystać z mozliwości łaczenia się z bazą danych danego producenta zazwyczaj należy zaopatrzyć się w konkretne sterowniki. Co ciekawe kod łaczenia się z bazą danych będzie zazwyczaj taki sam dla wszystkich dostawców, jedyne co należy wymienić to sterownik (o ile nie chcemy korzystać ze specyficznych dla danej bazy danych funkcjonalności - wtedy należy zrezygnować z korzystania z DriverManager i napisać cały kod ręcznie).
Sterowniki dostępu do baz danych dla Javy nazywane są JDBC i jesli ktoś chce się połaczyć z jakąś bazą danych najczęsciej poszukuje w google słów [nazwa bazy danych] JDBC, a google zazwyczaj wyświetla stronę ze sterownikami jak i wiele tutoriali jak ich użyć. Najpopularniejsze sterowniki dla baz danych:
Poniżej znajduje się kod aplikacji okienkowej komunikującej się z bazą danych. Projekt NetBeans można pobrać tutaj i od razu skompilować (oczywiście po dodaniu brakujących bibliotek - linki do pobrania znajują się powyżej - nalezy pobrać MS SQL Server Driver Microsoftu lub jTDS Driver).
Pobierz projekt NetBeansUWAGA biblioteki dodajemy najprościej (w obu typach projektów) klikając w katalog Libraries prawym klawiszem i wybierając Add jar/folder
/* * TestForm.java * * Created on 2012-01-18, 14:02:18 */ package test; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.sql.Types; import javax.swing.JOptionPane; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; /** * @author Robson */ public class TestForm extends javax.swing.JFrame { //nazwa użytkownika //nie Windows Authentication - trzeba go stworzyć w Security/Logins //oraz nadać mu uprawnienia odpowiednie do bazy danych test //dodatkowo w przykłądzie zakłądamy, że została dla niego ustawiona //default baza danych jako test String dbUser = "test"; //hasło dla usera //tworząc hasło w Security/Logins warto wyłaczyć Enforce password policy //w przeciwnym wypadku system nie pozwoli na tak proste hasło String dbPass = "tajnehaslo"; //adres bazy danych - nazwa_komputera\nazwa_instancji //domyślna nazwa instancji dla MS SQL Server Express Edition to SQLEXPRESS String dbAddress = "MACHINAZAGLADY4\\SQLEXPRESS"; //jesli używamy MS SqL Driver //String dbAddress = "MACHINAZAGLADY4;instance=SQLEXPRESS"; //jesli używamy jTDS Driver, //przy czym domyślna instancja nie działa - nalezy użyć samej nazwy servera //String dbAddress = "MACHINAZAGLADY4"; //jesli używamy jTDS Driver dla domyślnej instancji //Nazwa klasy sterownika JDBC i string wyboru sterownika - dwie linnie dla każdego z typu sterowników! String dbDriverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; //jesli uzywamy MSSQL Driver String dbDriverSelect = "jdbc:sqlserver://";//jesli uzywamy MSSQL Driver //String dbDriverClass = "net.sourceforge.jtds.jdbc.Driver"; //jeśli używamy jTDS driver //String dbDriverSelect = "jdbc:jtds:sqlserver://"; //jeśli używamy jTDS driver Connection connection = null; //pomocnicza funkcja - pobiera wszystkie dane z tabeli void refreshTable() { try { //tworzymy obiekt zapytań (statement) Statement statement = connection.createStatement(); //tworzymy dane dla tabeli - tzw. Model //dla ciekawskich: można poczytać o idei Model-View-Controller w Swing Statement countStmt = connection.createStatement(); ResultSet countRs = countStmt.executeQuery("select count(*) from t1"); countRs.next(); TableModel model = new DefaultTableModel(new String[]{"Id", "Nazwa", "Ilosc"}, countRs.getInt(1)); //UWAGA DO POWYŻSZEGO: //niestety DefaultTableModel - jedyny model dla tabeli domyślnie //dostępny w javie nie może mieć zmiennej ilości wierszy... //(dużo) lepszym rozwiązaniem byłoby zrobienie własnego modelu //przykład jak to zrobić jest tutaj: //http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data //Table model (i Column model) pozwala na bardzo dużą swobodę w tym co //można umieszczać w tabeli, możemy przykłądowo //umiescić w komórce nawet cały JPanel z przyciskami, polami edycji itp. //to jest związane z ideą MVC w Swing //wywołujemy zapytanie ResultSet rs = statement.executeQuery("select * from t1"); //pobieramy ilośc elementów (uwaga na batch'e!) int i = 0; //pobieramy wszystkie dane while (rs.next()) { //rs.next przesuwa kursor o jedną pozycję dalej, przy czym na //początku pozycja jest przed pierwszą daną (tak jakby na -1) //dzięki temu pętla wyciągająca dane jest prostsza int id = rs.getInt(1); //możemy pobierać po numerze kolumny int ilosc = rs.getInt("ilosc"); //albo po nazwie pola (zalecane) String nazwa = rs.getString("nazwa"); //warto określić jaki typ danych chcemy pobrać //(nie trzeba potem rzutować) //UWAGA: we własnym TableModel można poniższe rozwiązać ładniej! model.setValueAt(id, i, 0); model.setValueAt(nazwa, i, 1); model.setValueAt(ilosc, i, 2); i++; } mainTable.setModel(model); } catch (Exception e) { e.printStackTrace(); } } /** Creates new form TestForm */ public TestForm() { initComponents(); try { Class.forName(dbDriverClass); System.out.println("Connection string := "+dbDriverSelect + dbAddress); connection = DriverManager.getConnection(dbDriverSelect + dbAddress, dbUser, dbPass); } catch (Exception e) { System.out.println("Nie udało się połączyć: "); e.printStackTrace(); } refreshTable(); } private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed // TODO add your handling code here: String nazwa = nazwaText.getText(); int ilosc = -1; try { ilosc = Integer.parseInt(iloscText.getText()); } catch (Exception e) { //gdyby ktoś źle wpisał, możemy dac mu znać JOptionPane.showMessageDialog(this, "Niepoprawna watość!"); return; } try { //callable statement słuzy do wywoływania funkcji i procedur //jeśli chcemy wywołać funkcję, która zwraca skalar //możemy to zrobić pisząc jako parametr //"{call ? = sp_add_to_t1(?, ?, ?)}" //i zmieniając typ pierwszego parametru na OUT (zobacz poniżej) CallableStatement statement = connection.prepareCall("{call sp_add_to_t1(?, ?, ?)}"); //ustaw pierwszy parametr (zwróć uwagę na typ) statement.setString(1, nazwa); //ustaw drugi parametr (zwróc uwagę na typ) statement.setInt(2, ilosc); //ustaw 3 parametr jako OUT (zwracający dane) statement.registerOutParameter(3, Types.INTEGER); //wykonaj zapytanie (wszystkie parametry musza być określone inaczej exception) statement.execute(); //pobierz zwróconą wartość int id = statement.getInt(3); //wyświetl ją JOptionPane.showMessageDialog(this, "Dodano nowy wiersz o id = " + id); //odswież tabelę refreshTable(); //gdyby procedura zwróciła jakieś dane to można je tu jeszcze pobrać //while (rs.next()) { //} } catch (Exception e) { e.printStackTrace(); } }//GEN-LAST:event_addButtonActionPerformed //KOD PONIŻEJ ZOSTAŁ WYGENEROWANY AUTOMATYCZNIE PRZEZ EDYTOR NETBEANS //wyrzuciłem jego część, gdyż nie wnosi nic do projektu, a tylko zaciemnia i //rozciąga stronę - kompilujący się kod można pobrać z linku na mojej stronie /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new TestForm().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addButton; private javax.swing.JTextField iloscText; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTable mainTable; private javax.swing.JTextField nazwaText; // End of variables declaration//GEN-END:variables /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { //... (tutaj wyciąłem kod budujący formatkę) }// </editor-fold>//GEN-END:initComponents }
Projekt NetBeans można pobrać tutaj i od razu skompilować (oczywiście po dodaniu brakujących bibliotek - linki do pobrania znajują się powyżej - nalezy pobrać MS SQL Server Driver Microsoftu lub jTDS Driver).
UWAGA biblioteki dodajemy najprościej (w obu typach projektów) klikając w katalog Libraries prawym klawiszem i wybierając Add jar/folder
Pobierz projekt NetbeansNie będę wklejał całego kodu tutaj, gdyż jest już bardziej skomplikowany i podzielony siłą rzeczy (technologii JSP) na wiele plików. Najwazniejsze to zapamiętać:
Poniżej zamieszczam krótki poradnik, jak dodac nową funkcję w przykładowej aplikacji.
Powiedzmy, że chcemy dodać opcję wyszukiwania po nazwie w naszej tabeli T1. Wykonując poniższe instrukcje nalezy pamiętać o pojawiających się żaróweczkach z informacjami o błędach - pozwalają one bardzo łatwo usunąc te błędy, zazwyczaj wybieramy po prostu klikając w nie pierwszą proponowaną podpowiedź (choć czasem warto się na chwilę zatrzymać i zastanowić, szczególnie gdy mamy bardzo wiele podpowiedzi).
Klikamy prawym klawiszem na nazwie pakietu z servletami i klikamy New->Servlet... (jesli nie ma go na liście to Other... i znajdujemy go w odpowiedniej zakładce). pisujemy nazwę jaka się nam podoba np. SearchServlet, klikamy next. W następnym okienku możemy skonfigurować plik web.xml dla naszego servletu. Zaznaczamy add information to application descriptor (web.xml) (lub podobnie brzmiący checkbox). Wypełniamy: servlet name (dowolny, może być taki jak nazwa klasy), URL patterns - tutaj wpisujemy jaki ma być adres servletu - to jest wazne, gdyż to będziemy zwracać jako return w innych servletach, które będą chciały wywołać ten servlet, np. na stronie JSP w atrybucie action formatki HTML. Klikamy finish.
Pojawia się klasa servletu z funkcją processRequest() którą nalezy uzupełnić. Jesli jestesmy ciekawscy możemy rozwinąć ukryte częscie przez Netbeans'a i zobaczyć że processRequest jest wywoływany przez doPost() i doGet() (jak myślisz, dlaczego?).
Wpiszmy następujący kod:
String pole_nazwa; if ((pole_nazwa = request.getParameter("pole_nazwa")) != null) { Database db = new Database(); List<EncjaT1> lista = db.findAll(pole_nazwa); HttpSession s = request.getSession(); s.setAttribute("found", lista); } response.sendRedirect("SearchView");Kod nie będzie chciał się skompilować, gdyż nie ma funkcji findAll w Database.
public List<EncjaT1> findAll(String szukana) { List<EncjaT1> ret = new LinkedList<EncjaT1>(); try { //tworzymy obiekt zapytań (statement) Statement statement = connection.createStatement(); //wywołujemy zapytanie, wklejanie zmiennych w zapytanie w ten sposób //jest bardzo złą praktyką - lepiej zrobić funkcję //składowaną i zrobić callable statement lub jeśli już musimy robić //zapytanie, to wykorzystać PreparedStatement //(poczytać w dokumentacji) ResultSet rs = statement.executeQuery("select * from t1 where nazwa = '" + szukana + "'"); //pobieramy ilośc elementów (uwaga na batch'e!) while(rs.next()){ int id = rs.getInt(1); String nazwa = rs.getString(2); int ilosc = rs.getInt(1); ret.add(new EncjaT1(id, ilosc, nazwa)); } } catch (Exception e) { e.printStackTrace(); } return ret; }
teraz tworzymy ostatni element - widok wyświetlający dane. Klikamy w folder WEB-INF i wybieramy New->JSP, nazywamy ją searchview. W sekcji <body> wpisujemy:
<form action = "SearchServlet" method = "POST"> Nazwa: <input type = "text" name = "pole_nazwa"/> <br/> <input type = "submit" value = "szukaj"> </form> <table> <tr><th>Id</th><th>Nazwa</th><th>Ilość</th></tr> <% List<EncjaT1> tabelaT1 = (List<EncjaT1>)session.getAttribute("found"); if (tabelaT1!=null){ for (EncjaT1 encja : tabelaT1){ out.print("<tr><td>"+encja.getId() +"</td><td>"+encja.getNazwa() +"</td><td>"+encja.getIlosc() +"</td></tr>"); } } %> </table>
Teraz zostaje dodać informacje do deskryptora projektu (web.xml), aby zadziałał ładnie redirect w servlecie.
W pliku web.xml dodajemy linie
<servlet> <servlet-name>SearchView</servlet-name> <jsp-file>/WEB-INF/searchview.jsp</jsp-file> </servlet> <servlet-mapping> <servlet-name>SearchView</servlet-name> <url-pattern>/SearchView</url-pattern> </servlet-mapping>Znaczenia poszczególnych wpisów można się domyśleć. Servlet-mapping pozwala przypisywac servletom ładne url-e, natomiast znacznik servlet pozwala definiować servlety poprzez podanie ich klasy lub strony jsp z kórej będą wygenerowane.
Nie jest to jedyne rozwiązanie - można je łatwiej nawet zrobić pisząc kod servletu wyszukującego w stronie JSP, ale chciałem pokazać jak mozna to zrobić w pełnej krasie.
Poniżej znajduje się kod aplikacji okienkowej komunikującej się z bazą danych. Projekt Visual Studio można pobrać tutaj i od razu skompilować. Visual Studio Express Edition można pobrać tutaj: Visual Studio 2008 Express Edition - nalezy pobrać paczkę vcssetup.exe. Mozna tez zainstalować sobie lepszą wersję z MSDNAA na naszej uleczelni: http://msdn.ii.uj.edu.pl.
Za pomoc w stworzeniu tego materiału chciałbym podziękować panu Szymonowi Stawickiemu.
Pobierz projekt VS2008Poniżej kod:
public partial class Form1 : Form { //to jest porzebne, aby wyświetlić dane w tabelce private BindingSource bindingSource1 = new BindingSource(); //ten connection string pozwala łączyć się poprzez windows authentication i co ciekawe - działa :) //ale to pewnie dlatego, że korzystamy w całości z technologii firmy Microsoft :) string strConnection = @"Provider=SQLOLEDB.1;Integrated Security=SSPI;Data Source=MACHINAZAGLADY4\SQLEXPRESS;Initial Catalog=test"; //a to pozwala łaczyć się tak jak w pozostałych przypadkach //string strConnection = // @"Provider=SQLOLEDB.1;Password=tajnehaslo;Persist Security Info=True;"+ // "User ID=test;Data Source=MACHINAZAGLADY4\SQLEXPRESS;Initial Catalog=test"; //tworzy tabelkę z danymi - dodaje kolumny itp. public void tableInit() { //aby nie tworzył sam kolumn //czasem C# potrafi sam je zrobić np. na podstawie danych z tabeli z //bazy danych, ale tym razem robimy to sami - gdyż korzystamy z obiektów //a nie z klasy DataSet'u (dla ciekawskich - można o tym poczytać) dataGridView1.AutoGenerateColumns = false; dataGridView1.AutoSize = false; dataGridView1.DataSource = bindingSource1; //nowa kolumna DataGridViewColumn columnId = new DataGridViewTextBoxColumn(); columnId.DataPropertyName = "Id"; columnId.Name = "ID"; dataGridView1.Columns.Add(columnId); //nowa kolumna DataGridViewColumn columnNazwa = new DataGridViewTextBoxColumn(); columnNazwa.DataPropertyName = "Nazwa"; columnNazwa.Name = "Nazwa"; dataGridView1.Columns.Add(columnNazwa); //nowa kolumna DataGridViewColumn columnIlosc = new DataGridViewTextBoxColumn(); columnIlosc.DataPropertyName = "Ilosc"; columnIlosc.Name = "Ilość"; dataGridView1.Columns.Add(columnIlosc); //dodajemy testowy obiekt bindingSource1.Add(new EncjaT1(0, "TEST", 123)); } //łączy się z bazą i wypełnia tabelkę danymi public void refreshTable() { //jak widać z poniższego OleDbConnection connection = null; OleDbDataReader reader = null; try { //tworzymy połączenie connection = new OleDbConnection(this.strConnection); //łączymy się connection.Open(); //tworzymy nowe polecenie OleDbCommand command = new OleDbCommand("SELECT id, nazwa, ilosc FROM T1", connection); reader = command.ExecuteReader(); //wyczyśmy stare dane bindingSource1.Clear(); //czytamy dane while (reader.Read()) { //w C# kolumny numerowane od zera... int id = reader.GetInt32(0); string nazwa = reader.GetString(1); int ilosc = reader.GetInt32(2); bindingSource1.Add(new EncjaT1(id, nazwa, ilosc)); } } catch (Exception e) { MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } finally { connection.Close(); reader.Close(); } } public void addNewtoT1(){ OleDbConnection connection = null; string nazwa = textBox1.Text; int ilosc = -1; try { ilosc = int.Parse(textBox2.Text); //nowe połączenie connection = new OleDbConnection(this.strConnection); connection.Open(); //procedura OleDbCommand command = new OleDbCommand("sp_add_to_t1", connection); command.CommandType = CommandType.StoredProcedure; //parametry command.Parameters.Add("@nazwa", OleDbType.VarChar, 256); command.Parameters.Add("@ilosc", OleDbType.Integer); command.Parameters.Add("@lastId", OleDbType.SmallInt); //wartości command.Parameters["@nazwa"].Value = nazwa; command.Parameters["@ilosc"].Value = ilosc; command.Parameters["@lastId"].Direction = ParameterDirection.Output; //kierunek //wywołujemy coś, co nie zwraca danych - mówimy systemowi żeby nie zwracał resultSeta (readera) command.ExecuteNonQuery(); //pobieramy zwróconą wartość string lastId = command.Parameters["@lastId"].Value.ToString(); MessageBox.Show(lastId, "Dodano", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception e) { MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } public Form1() { InitializeComponent(); //wywołujemy stworzenie struktury tabelki tableInit(); //wypełniamy tabelkę refreshTable(); } private void button1_Click(object sender, EventArgs e) { addNewtoT1(); refreshTable(); } } public class EncjaT1 { public string Nazwa { get; set; } public int Id { get; set; } public int Ilosc { get; set; } public EncjaT1() { } public EncjaT1(int id, string nazwa, int ilosc) { this.Nazwa = nazwa; this.Id = id; this.Ilosc = ilosc; } }