MySQLDatabases/pl

From Lazarus wiki
Revision as of 13:39, 31 January 2021 by Slawek (talk | contribs) (→‎The main form: tłumaczenie na j. polski)
Jump to navigationJump to search

Deutsch (de) English (en) français (fr) 日本語 (ja) polski (pl) slovenčina (sk)

Databases portal

References:

Tutorials/practical articles:

Databases

Advantage - MySQL - MSSQL - Postgres - Interbase - Firebird - Oracle - ODBC - Paradox - SQLite - dBASE - MS Access - Zeos

Wprowadzenie

Ta strona wyjaśnia, jak połączyć się z serwerem bazy danych MySQL przy użyciu komponentów wizualnych.

Light bulb  Uwaga: Ta strona została przetłumaczona z wersji angielskiej na język polski w dniu 2021.01.31, ale wersja angielska została napisana dawno temu i może nie być aktualna. Ponadto większość opisanych tutaj koncepcji nie jest specyficznych dla MySQL, ale ma zastosowanie do wszystkich baz danych SQLDB. Dlatego skorzystanie z poniższej serii samouczków SQLdb może być łatwiejsze

Uwaga: zapoznaj się również z samouczkami, które uczą obsługi kontrolek związanych z danymi, zapytań parametrycznych, programowania niezależnego od bazy danych itp .:

Te samouczki są napisane dla wszystkich baz danych obsługujących sqldb, w tym MySQL.

W razie potrzeby zobacz również Samouczki SQLDB i przykładowy kod, aby uzyskać więcej samouczków (które również zostały napisane dawno temu.

Dostępne komponenty

Komponenty SQLdb

W każdej, nawet dość niedawnej wersji Lazarusa, komponenty SQLdb są instalowane domyślnie.

sqldbcomponents.png

W zakładce SQLdb znajdziesz:

  • Różne złącza (connectors), w tym TMySQL40Connection .. TMySQL57Connection (a może nawet nowsze wersje) i najbardziej wszechstronne ze wszystkich TSQLConnector, które mogą ładować dowolne ze sterowników baz danych takich jak mysql/oracle/postgres/mssql/interbase/firebird/odbc.
  • TSQLQuery

Jeśli brakuje karty SQLdb, zajrzyj do Instalowanie pakietów, aby uzyskać instrukcje dotyczące instalacji.

Wyjaśnienie zastosowanych komponentów

TMySQLConnection

TMySQLConnection służy do przechowywania parametrów połączenia z serwerem bazy danych. Umożliwia ustawienie hosta, z którym ma się łączyć, oraz identyfikatora użytkownika i hasła, które mają być używane w połączeniu. Inna właściwość TMySQLConnection służy do wskazania bazy danych, której chcesz użyć. „LoginPrompt” jeszcze nie działa, więc upewnij się, że obok właściwości HostName i DatabaseName uzupełnione są również wartości UserName i Password, zanim spróbujesz otworzyć połączenie. Pamiętaj, że aby użyć również TSQLTransaction i połączyć ją z MySQLConnection, ustaw właściwość Transaction, w przeciwnym razie nie będziesz mógł otworzyć zapytania SQLQuery.

Light bulb  Uwaga: Jak wskazano powyżej, istnieją różne komponenty MySQLConnection, które różnią się numerem wersji. Numer wersji musi odpowiadać numerowi wersji biblioteki klienta, której używasz do łączenia się z serwerem. Jeśli więc używasz serwera MySQL 5.1, ale używasz klienta MySQL 5.0, użyj TMySQL50Connection.

Powinieneś sprawdzić dokumentację MySQL, aby upewnić się, że połączenie między wersją klienta i wersją serwera jest obsługiwane - np. możesz mieć problemy z połączeniem się z serwerem 4.0 przy użyciu klienta 5.x.

We wszystkich przypadkach należy umieścić kopię biblioteki libmysql.dll i wszelkich innych wymaganych plików/bibliotek dll

  • w twoim katalogu Lazarus i tym samym katalogu co pliki twojego projektu lub
  • w katalogu systemowym Windows (jeśli nie chcesz dalej kopiować plików). Zauważ, że w 64-bitowym systemie Windows bibliotekę 32-bitową musisz umieścić w katalogu SysWOW64, podczas gdy biblioteki 64-bitowe należy przenieść do System32.

TSQLTransaction

TSQLTransaction jest potrzebne do niektórych wewnętrznych procedur. SQLTransaction jest automatycznie aktywowana po otwarciu zestawu danych przy jej użyciu. Zamknięcie połączenia również dezaktywuje powiązaną transakcję i zamyka wszystkie korzystające z niej zbiory danych.

TSQLQuery

TSQLQuery służy do wykonywania instrukcji SQL na serwerze. Możesz pobrać dane, ustawiając SQL na jakąś instrukcję SELECT i wywołując metodę Open. Możesz też manipulować danymi, wydając instrukcję INSERT, DELETE lub UPDATE. W tym drugim przypadku nie powinieneś używać metody Open, ale metodę ExecSQL.

TDataSource

TDataSource zapewnia połączenie między widocznymi komponentami obsługującymi dane, takimi jak DBEdit, DBGrid i zbiorem danych. Przygotowuje dane do wyświetlania w komponentach obsługujących te dane. DataSource (źródło danych) może być jednocześnie połączone tylko z jednym zestawem danych, ale do niego może być połączonych kilka komponentów obsługujących dane.

TDBGrid

TDBGrid może służyć do przedstawienia danych pobranych przez Dataset (zbiór danych). DBGrid potrzebuje Datasource (źródła danych), aby połączyć się ze zbirem danych. Gdy zbiór danych zostanie otwarty, DBGrid zostanie automatycznie wypełniony danymi.

Our program

Podstawy

Spróbujemy stworzyć program w oparciu o ten stworzony tutaj (w języku niderlandzkim), który jest oparty na oryginał (w języku angielskim) autorstwa Chris.

Formularz główny

Użyjemy tego samego ekranu głównego i zbudujemy całą funkcjonalność od podstaw :) Jak zobaczysz, jest tu o wiele mniej do zrobienia, ponieważ komponenty naprawdę rozwiązują wszystkie trudne rzeczy! Zacznijmy więc od stworzenia ekranu, który wygląda tak:

Trymysql.png

Korzystając z zakładki SQLdb umieść na swojej formatce komponenty TMySQL56Connection tmysql56connection.png (lub inną wersję klienta mysql), TSQLTransaction tsqltransaction.png i TSQLQuery tsqlquery.png. Nie zmieniaj domyślnych nazw nadanych tym komponentom. Z wyjątkiem komponentu łączącego do bazy. Aby artykuł był taki sam dla wszystkich wersji MySQL, nazwij komponent TMySQL##Connection: MySQLConnection1. Musimy te komponenty połączyć razem, aby mogły wykonywać swoją pracę. Dlatego należy ustawić następujące właściwości:

Component Property Value
MySQLConnection1 Transaction SQLTransaction1
SQLTransaction1 Database MySQLConnection1
SQLQuery1 Transaction SQLTransaction1
SQLQuery1 Database MySQLConnection1

Właściwość Transaction komponentu SQLQuery1 zostanie ustawiona automatycznie, jeśli najpierw ustawisz właściwość Transaction dla MySQLConnection1. Gdy to ustawisz, zauważysz, że SQLTransaction1.Database została ustawiona na MySQLConnection1.

Jak wspomniano wcześniej: upewnij się, że używasz odpowiedniego komponentu połączenia dla swojej wersji serwera MySQL.

The code

As you can see in the screen dump the only buttons available on start of the program are "Connect to server" and "Exit". For the other buttons to work we need more information so these are disabled. We could decide to disable "Connect to Server" as well until the information for the host, username and password has been given. I decided against this because our user might think: "Nothing seems possible, so let's hit exit." :)

Before I start giving you any code I would like to stress that there should be more exception handling in the code. Critical sections should be placed in

try ... finally

or

try ... except

constructions.

Connect to a server

The first thing we have to do is get connected to our server. As when connecting we don't know what databases are available on the server we will ask for a list of databases on connecting. However there is one catch, to make the connection we have to enter a valid DatabaseName in the properties of the MySQLConnection. You will see in the code that I am using the "mysql" database. This database is used by mysql for some housekeeping so it will always be there.

procedure TFormTryMySQL.ConnectButtonClick(Sender: TObject);
begin
  // Check if we have an active connection. If so, let's close it.
  if MySQLConnection1.Connected then CloseConnection(Sender);
  // Set the connection parameters.
  MySQLConnection1.HostName := HostEdit.Text;
  MySQLConnection1.UserName := UserEdit.Text;
  MySQLConnection1.Password := PasswdEdit.Text;
  MySQLConnection1.DatabaseName := 'mysql'; // MySQL is allways there!
  ShowString('Opening a connection to server: ' + HostEdit.Text);
  MySQLConnection1.Open;
  // First lets get a list of available databases.
  if MySQLConnection1.Connected then begin
    ShowString('Connected to server: ' + HostEdit.Text);
    ShowString('Retrieving list of available databases.');
    SQLQuery1.SQL.Text := 'show databases';
    SQLQuery1.Open;
    while not SQLQuery1.EOF do begin
      DatabaseComboBox.Items.Add(SQLQuery1.Fields[0].AsString);
      SQLQuery1.Next;
    end;
    SQLQuery1.Close;
    ShowString('List of databases received!');
  end;
end;

The first thing we do is check to see if we are connected to a server, if we are then we call a private method "CloseConnection". In this method some more housekeeping is done. like disabling buttons and clearing comboboxes and listboxes. Then we set the necessary parameters to connect to server.

Throughout our program you may see calls to ShowString. This method adds a line to the memo on our form which acts like a kind of log.

With the parameters set, we can connect to the server. This is done by calling

MySQLConnection1.Open;

In a proper application one would place this in an exception handling construct to present a friendly message to the user if the connection failed. When we are connected we want to get a list of databases from the server. To get data from the server a TSQLQuery is used. The SQL property is used to store the SQL-statement send to the server. MySQL knows the "SHOW DATABASES" command to get the list of databases. So after we have set the SQL-text, we call

SQLQuery1.Open;

On MySQL5 set this to correct error with SQL syntax:

SQLQuery1.ParseSQL := False; 
SQLQuery1.ReadOnly := True;

The result set of a SQLQuery can be examined through the fields property. As you can see we iterate through the records by calling

SQLQuery1.Next;

When we have added all available databases to our combobox, we close the SQLQuery again.

Selecting a database

If the user selects a database in the DatabaseComboBox we enable the "Select Database" button. In the OnClick event of this button we set the DatabaseName of MySQLConnection1, and request a list of tables. The last statement of this procedure enables the "Open Query" Button, so the user can enter a query in the "Command" Editbox and have it send to the server.

procedure TFormTryMySQL.SelectDBButtonClick(Sender: TObject);
begin
  // A database has been selected so lets get the tables in it.
  CloseConnection(Sender);
  if DatabaseComboBox.ItemIndex <> -1 then begin
    with DatabaseComboBox do
      MySQLConnection1.DatabaseName := Items[ItemIndex];
    ShowString('Retreiving list of tables');
    SQLQuery1.SQL.Text := 'show tables';
    SQLQuery1.Open;
    while not SQLQuery1.EOF do begin
      TableComboBox.Items.Add(SQLQuery1.Fields[0].AsString);
      SQLQuery1.Next;
    end;
    SQLQuery1.Close;
    ShowString('List of tables received');
  end;
  OpenQueryButton.Enabled := True;
end;

MySQL has a special command to get a list of tables, comparable to getting the list of databases, "show tables". The result of this query is handled in the same way as the list of databases and all the tables are added to the TableComboBox. You might wonder why we do not open the connection again before opening the query? Well, this is done automatically (if necessary) when we activate the SQLQuery.

Fields in a table

In MySQL you can again use a form of "SHOW" to get the fields in a table. In this case "SHOW COLUMNS FROM <tablename>". If the user picks a table from the TableComboBox the OnChangeEvent of this ComboBox is triggered which fills the FieldListbox.

procedure TFormTryMySQL.TableComboBoxChange(Sender: TObject);
begin
  FieldListBox.Clear;
  SQLQuery1.SQL.Text := 'show columns from ' + TableComboBox.Text;
  SQLQuery1.Open;
  while not SQLQuery1.EOF do begin
    FieldListBox.Items.Add(SQLQuery1.Fields[0].AsString);
    SQLQuery1.Next;
  end;
  SQLQuery1.Close;
end;

As well as the names of the fields, the result set contains information on the type of field, if the field is a key, if nulls are allowed and some more.

Showing the data

Well as we said we would use components to get connected to the database, lets use some components to show the data as well. We will use a second form to show a grid with the data requested by the user. This form will be shown when the user typed a SQL command in the "Command" editbox and afterwards clicks the "Open Query" button. This is the OnClick event:

procedure TFormTryMySQL.OpenQueryButtonClick(Sender: TObject);
begin
  ShowQueryForm := TShowQueryForm.Create(self);
  ShowQueryForm.Datasource1.DataSet := SQLQuery1;
  SQLQuery1.SQL.Text := CommandEdit.Text;
  SQLQuery1.Open;
  ShowQueryForm.ShowModal;
  ShowQueryForm.Free;
  SQLQuery1.Close;
end;

The ShowQueryForm looks like this:

Mysqlshow.png

and contains a

TPanel Align alBottom
TDataSource
TDBGrid Align alClient
DataSource DataSource1
TButton Caption Close

The button is placed on the panel. What happens in the "Open Query" OnClick is this. First we create an instance of TShowQueryForm. Secondly we set the DataSet property of the DataSource to our SQLQuery1. Then we set the SQLQuery SQL command to what the user entered in the "Command" editbox and open it. Then the ShowQueryForm is shown modally, this means that it will have the focus of our application until it is closed. When it is closed, we "free" it and close SQLQuery1 again.

The Form can be further enhanced by inserting a method for modifying the content of the TDataSet and ultimately the DataBase. A full version can be downloaded from http://digitus.itk.ppke.hu/~janma/lazarus/MySql5Test.tar.gz (with thanks to Arwen and JZombi from the Lazarus MySQL Forum) but the relevant details are as follows:

Add a Button at the bottom of the ShowQuery Form named AddButton and with Caption 'Add'. Create a method for AddButtonClick like this:

procedure TShowQueryForm.AddButtonClick(Sender: TObject);
begin
  DataSource1.DataSet.Append;
end;

Change the code for OpenQueryButtonClick to allow for updates to the database when we finish with the Query Form.

procedure TFormTryMySQL.OpenQueryButtonClick(Sender: TObject);
begin
  ShowQueryForm := TShowQueryForm.Create(nil);
  try
    ShowQueryForm.DataSource1.DataSet := SQLQuery1;
    // We will write in the database, so let's set ReadOnly to false, 
    // and for that we need to set ParseSQL true
    SQLQuery1.ParseSQL:=true;
    SQLQuery1.ReadOnly:=false;
    SQLQuery1.SQL.Text := CommandEdit.Text;
    SQLQuery1.Open;
    ShowQueryForm.ShowModal;
  finally
    // set up update mode, and update database
    SQLQuery1.UpdateMode:=upWhereChanged;
    SQLQuery1.ApplyUpdates;
    SQLTransaction1.Commit;
    ShowQueryForm.Free;
    SQLQuery1.Close;
    // set read-only and parsesql back to default
    SQLQuery1.ParseSQL:=false;
    SQLQuery1.ReadOnly:=true;
  end;
end;

We can now add records to the Database. If we add a TDBNavigator to the ShowQuery Form we can move around the Data Grid more easily, and edit records; the database gets updated with our changes each time we close the ShowQuery Form, and we can test this by opening it up again to inspect the database.

If you want to be able to DELETE or otherwise modify records on the original database (ie make sure changes you make to the local dataset get committed back to the database) then you need to have one column in your database table that is a primary key autoincremented, as the 'delete' method requires to be able to generate a 'where' clause when writing instructions back to the database, to identify the records selected for deletion. So use the following code in your MySQL client (it can all be typed on one line, but line breaks have been added for clarity):

ALTER TABLE TRESTRIG 
ADD COLUMN AUTOID INT 
PRIMARY KEY AUTO_INCREMENT;

and then you will find that the Delete button on the navigator works.

Sources

The sources for this project can be downloaded here For more demo projects see sourceforge

See also