Vous êtes sur la page 1sur 26

1 2

Objetivo
Programao I
Criar uma interface mais sofisticada para o uso do MySQL em
Lazarus.

Aprender a criar um banco de dados MySQL e a usar a API


Aula 15: BD com API avanada: MySQL 4 de programao para executar funes simples de acesso
e consulta.

Mrio Benevides
Paulo Roma
3 4 5 6

Componentes utilizados Componentes utilizados Componentes utilizados Componentes utilizados


TForm

TButton TMemo TListBox TListView

TLabel
TComboBox

TStatusBar
TEdit

7 8 9 10

Funes Utilizadas Funes Utilizadas Funes Utilizadas Funes Utilizadas


Lista das 14 funes do MySQL utilizadas (declaradas em C): Lista das 14 funes do MySQL utilizadas (declaradas em C): Lista das 14 funes do MySQL utilizadas (declaradas em C): Lista das 14 funes do MySQL utilizadas (declaradas em C):

MYSQL* mysql_real_connect ( MYSQL *mysql, MYSQL_RES *mysql_list_dbs (MYSQL *mysql, const char *wild) int mysql_query (MYSQL *mysql, const char *query)
MYSQL *mysql_init (MYSQL *mysql) const char *host,
const char *user, Retorna um conjunto resultado que consiste dos nomes dos Executa a consulta SQL apontada pela string no nula query.
Aloca ou inicia um objeto MYSQL adequado chamada const char *passwd, Bancos de Dados do servidor que satisfazem a expresso A consulta deve consistir de um nico comando SQL.
da funo mysql_real_connect(). const char *db, regular especificada no parmetro wild. wild pode conter os No deve ser adicionado um terminador " ; " ou \g ao comando.
unsigned int port, caracteres % ou _ (wild cards), ou pode ser um ponteiro NULL,
const char *unix_socket, que significa todos os bancos de dados. mysql_query() no pode ser usada para consultas que
unsigned long client_flag) contenham dados binrios; neste caso, deve ser usada
MYSQL_RES *mysql_list_tables (MYSQL *mysql, const char *wild) a funo mysql_real_query() .
Tenta estabelecer uma conexo com um banco de dados (Dados binrios podem conter o caracter \0, que o mysql_query()
MySQL rodando em host. Esta funo deve ser completada Retorna um conjunto resultado que consiste dos nomes das interpreta como o final da string de consulta).
sem erro antes que se possa executar qualquer outra chamada tabelas do banco de dados corrente que satisfaz uma expresso
de funo da API. Retorna um ponteiro (*MYSQL) para o handle regular simples especificada pelo parmetro wild. wild pode conter Retorna zero se a consulta foi bem sucedida ou
da conexo em caso de sucesso ou NULL, em caso de fracasso. os caracteres % ou _ (wild cards), ou pode ser o ponteiro NULL, um valor diferente de zero, se ocorreu algum erro.
que significa todas as tabelas.

11 12 13 14

Funes Utilizadas Funes Utilizadas Funes Utilizadas Funes Utilizadas


Lista das 14 funes do MySQL utilizadas (declaradas em C): Lista das 14 funes do MySQL utilizadas (declaradas em C): Lista das 14 funes do MySQL utilizadas (declaradas em C): Lista das 14 funes do MySQL utilizadas (declaradas em C):

MYSQL_ROW mysql_fetch_row (MYSQL_RES *result) void mysql_free_result (MYSQL_RES *result )


unsigned long mysql_num_rows (MYSQL_RES *result) MYSQL_FIELD *mysql_fetch_field_direct (
Retorna a prxima linha de um conjunto resultado ou NULL, Libera a memria alocada pelo conjunto resultado das funes MYSQL_RES *result,
se no houver mais linhas. mysql_store_result(), mysql_use_result(), mysql_list_dbs(), etc... Retorna o nmero de linhas (registros) de um conjunto resultado. unsigned int fieldnr)

Dado um nmero de campo fieldnr de uma coluna dentro de


um conjunto resultado, retorna a definio do campo desta
MYSQL_RES *mysql_store_result (MYSQL *mysql) int mysql_select_db ( MYSQL *mysql, const char *db) unsigned int mysql_num_fields (MYSQL_RES *result) coluna como uma estrutura MYSQL_FIELD .
Esta funo pode ser usada para recuperar a definio de
Deve-se chamar mysql_store_result() para cada query bem Faz com que o Banco de Dados especificado por db seja o Retorna o nmero de colunas (campos) de um conjunto resultado. uma coluna arbitrria. O valor do fieldnr deve estar no intervalo
sucedida que retorne dados (Select, Show, Describe, Explain). default(corrente) na conexo especificada por mysql. Em queries entre 0 e mysql_num_fields(result) -1.
O resultado completo de uma query do cliente lido, uma estrutura subsequentes, este banco de dados o default em todas as
MYSQL_RES alocada e recebe o resultado. referncias a tabelas que no incluam um especificador explcito.

15 16 17 18

Funes Utilizadas MySQL Desenvolver o Projeto Desenvolver o Projeto


Lista das 14 funes do MySQL utilizadas (declaradas em C): 1) Alterar as seguintes propriedades do Form: 2) Colocar no Form, como na figura, os controles relacionados a
Este projeto ensina a Caption - TryMySQL seguir: 3 TLabel e 3 TEdit
conectar o Lazarus ao (Name) - frmTryMySQL
const char *mysql_error (MYSQL *mysql) MySQL 4 e a executar
consultas simples,
Para a conexo especificada por mysql, retorna uma string usando apenas
terminada por NULL, contendo a mensagem de erro para a componentes Name = txtHost
funo da API invocada mais recentemente que falhou. bsicos do Lazarus.
Name = txtUsername

void mysql_close (MYSQL *mysql)


Name = txtPassword

Fecha uma conexo que foi aberta previamente, e desaloca o


handle de conexo apontado por mysql, se este foi alocado
automaticamente por mysql_init() ou mysql_connect().
19 20 21 22

Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto


3) Selecione o TEdit txtPassword 5) Coloque quatro TButton no formulrio: altere a propriedade Text para
e encontre a propriedade 4) Coloque um outro TEdit e TLabel no topo do lado direito do Connect to Server (btnConnect), Exit (btnExit), 6) Adicione duas
formulrio. Mude o label para Enter SQL Command. Chame o TEdit TComboBox no
PasswordChar. Mude-a para *, Select database (btnSelectDB) e Open Query (btnOpenQuery). Altere
de txtCommand. a propriedade Enabled dos botes Open Query e Select Database formulrio com
ou algum outro caracter, para
propriedade Name
que quando voc digite a senha os para False.
caracteres no apaream na tela, e cboDatabase e
apenas seja ecoado uma srie de *. Name = txtCommand
cboTable. Adicione
Certifique-se de que a propriedade tambm dois TLabel
Text de cada TEdit esteja em para identific-las:
branco. lblDatabase e lblTable,
Name = cboDatabase
com caption Database
e Tables,
respectivamente.
Deixe a propriedade Name = cboTable
Text do TComboBox
vazia.

23 24 25 26

Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto


7) Adicione um TListBox para conter os campos de uma tabela do banco 8) Adicione um TMemoBox com Name memResults. Limpe o seu
de dados selecionado. Chame-a de lstField e crie um TLabel contedo. Encontre a propriedade ScrollBars e selecione
associado a ela com o caption Fields. ssAutoBoth, para que os scroll bars apaream automaticamente
se o texto ocupar todo o espao. Torne verdadeira a propriedade
WordWrap.

Name = lstField

27 28 29 30
Desenvolver o Projeto
Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto
9) Adicione um TStatusBar (a partir da
aba Common Controls) e 10) Crie um segundo formulrio chamado frmShowQuery, para 11) Codificar a seguinte procedure para que as respostas do banco
mude a propriedade SimpleText exibir o resultado das consultas. Adicione a ele uma TListView e um de dados sejam convertidas em strings e exibidas no TMemo.
para TryMySQL. boto Close.
procedure TfrmTryMySQL.ShowString(const S: String);
// exibe uma string em um MemoBox
begin
memResults.Lines.Add(S);
end;
Name = lsvResult

Name = btnClose

31 32 33 34

Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto


12) Incluir na seo interface, do form TryMySQL, uma referncia 13) Incluir na seo interface uma referncia ao form Show Query. 14) Declarar as seguintes variveis, na seo implementation do form 15) No evento Click do boto Connect do form TryMySQL, codificar:
biblioteca mysql4 . TryMySQL, que sero usadas pelo programa:
procedure TfrmTryMySQL.btnConnectClick(Sender: TObject);
var
var databasenamesBuffer: PMYSQL_RES;
aDatabase: TMYSQL_ROW;
mySQLSock: PmySQL; begin
mySQLq: TmySQL; // Conecte ao servidor.
// Como temos { $H+ }, podemos fazer o cast de Strings para PChar
// sem problemas.
// Primeiro feche a conexo velha e limpe o cboDatabase, porque
// ele pode conter dados de uma conexo prvia.
if mySQLSock <> nil then begin
mysql_close (mySQLSock);
cboDatabase.Clear;
cboDatabaseChange(cboDatabase);
end;

continua ...
35 36 37 38

Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto


try
mySQLSock := mysql_real_connect ( mysql_init(PMYSQL(@mySQLq)), Screen.Cursor := crHourGlass;
PChar (txtHost.Text), // Estamos conectados, entao peguemos a lista de bancos disponiveis.
databasenamesBuffer := mysql_list_dbs (mySQLSock, nil); 16) No evento Click do boto OpenQuery do form TryMySQL, codificar: // No queremos ser pegos com um cursor Ampulheta.
PChar (txtUsername.Text), // Ento, coloque o cdigo relevante
PChar (txtPassword.Text), // Uma outra maneira de fazer isto, postando uma query como :
// SHOW DATABASES procedure TfrmTryMySQL.btnOpenQueryClick(Sender: TObject); // em uma try .. finally e reset o cursor na parte finally.
PChar (testdb), var try
0, nil, 0); // Veja o procedimento cboTableChange(Sender: TObject);
try I: Integer; if (mysql_query (mySQLSock, pChar(txtCommand.Text)) < 0)
if mySQLSock = nil then begin tableBuffer: PMYSQL_RES; then begin
ShowString(Conexo ao servidor falhou.); // Adicione cada banco de dados como um item ao cboDatabase.
aDatabase := mysql_fetch_row (databasenamesBuffer); recordBuffer: TMYSQL_ROW; ShowString (Query falhou + StrPas(mysql_error(mySQLSock)));
ShowString(O erro foi: + StrPas(mysql_error(@mySQLq))); aColumn: TListColumn; Raise(Exception.Create (Query falhou.));
end else begin while (aDatabase <> nil) do begin
cboDatabase.Items.Add(aDatabase[0]); field: PMYSQL_FIELD; end else begin
stbTryMySQL.SimpleText := Conectado ao servidor de banco de dados.; begin tableBuffer := mysql_store_result (mySQLSock);
ShowString (Host info : + StrPas(mysql_get_host_info (mySQLSock))); adatabase := mysql_fetch_row ( databasenamesBuffer);
end; // Um exemplo de como lidar com o dado retornado. // mysql_store_result retorna nil se nao houver nada a armazenar.
ShowString (Info do Servidor : + StrPas(mysql_stat (mySQLSock))); // Algum feedback extra com propsito de demonstrao. // Isto nao significa que a query estava errada.
ShowString (Info do Cliente : + Strpas(mysql_get_client_info)); finally
// finalmente, libere o resultado. stbTryMySQL.SimpleText := Executando query: + txtCommand.Text; // Pode acontecer da query nao ter um conjunto resultado.
{$ifdef Unix} ShowString(Executando query: + txtCommand.Text); if tableBuffer <> nil then begin
ShowString (Porta Mysql : + IntToStr(mysql_port)); mysql_free_result (databasenamesBuffer);
end; frmShowQuery := TfrmShowQuery.Create(nil); // De novo, algum feedback extra com proposito de demonstrao.
ShowString (Porta unix do Mysql : + StrPas(mysql_unix_port)); ShowString (Nmero de registros retornado : +
{$endif} end;
end; IntToStr(mysql_num_rows(tableBuffer)));
ShowString (Nmero de campos por registro: +
continua ... IntToStr(mysql_num_fields(tableBuffer)));
continua ... continua ...

39 40 41 42

Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto


try
frmShowQuery.lsvResults.Columns.Clear; // H mais registros para processar? 17) No evento Click do boto Select Database do form TryMySQL, end else begin
// Agora, ns vamos adicionar uma coluna para cada campo recordBuffer := mysql_fetch_row (tableBuffer);
// do conjunto resultado.
codificar: // Uma vez conectados ao banco de dados, peamos a lista de tabelas.
end; // while cboTable.Clear;
// O caption das colunas vem do nome dos campos. finally procedure TfrmTryMySQL.btnSelectDBClick(Sender: TObject); tablenamesBuffer := mysql_list_tables (mySQLSock, nil);
for I := 0 to pred (mysql_num_fields (tableBuffer)) do begin mysql_free_result (tableBuffer); var aTable := mysql_fetch_row (tablenamesBuffer);
aColumn := frmShowQuery.lsvResults.Columns.Add; end; tablenamesBuffer: PMYSQL_RES; // claro que "SHOW TABLES" funcionaria tambem.
field := mysql_fetch_field_direct (tableBuffer, I); end else begin aTable: TMYSQL_ROW; while (aTable <> nil) do begin
aColumn.Caption := PChar(field^.name); ShowString (Query nao retornou resultado algum.); begin cboTable.Items.Add(aTable[0]);
end; end; // Conecte ao banco de dados selecionado. aTable := mysql_fetch_row (tablenamesBuffer);
// Vejamos se a tabela contm dados e peamos o primeiro registro. end; if cboDatabase.ItemIndex <> -1 // no realmente necessrio mas ... end;
recordBuffer := mysql_fetch_row (tableBuffer); finally then begin mysql_free_result (tablenamesBuffer);
// Se no h (mais) registros, mysql_fetch_row retorna nil. Screen.Cursor := crDefault; ShowString (Selecionando um banco de dados : + btnOpenQuery.Enabled := True;
while (recordBuffer <> nil) do begin end; cboDatabase.Text); end;
// Temos alguns dados, ento adicionemo-os a nossa view. // O form foi preenchido com dados, ento vamos mostr-los. if mysql_select_db (mySQLSock, PChar(cboDatabase.Text)) < 0 end else begin
with frmShowQuery.lsvResults.Items.Add do begin frmShowQuery.ShowModal; then begin // Nunca se chega aqui, entao porque se preocupar?
Caption := recordBuffer[0]; // Preenchendo a primeira coluna finally // Em caso de falha, o boto Open Query no deve ser ativado. // Bem, nunca se sabe ...
for I := 1 to pred (mysql_num_fields (tableBuffer)) do frmShowQuery.Free; btnOpenQuery.Enabled := False; ShowMessage (Selecione um banco de dados no ComboBox.);
// Ento adicionemos os outros campos. end; // Mostre o que deu errado. end;
SubItems.Add(recordBuffer[I]); end; ShowString (No for possivel selecionar o banco de dados + end;
end; cboDatabase.Text);
continua ... ShowString(mysql_error (mySQLSock)); continua ...

43 44 45 46

Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto


18) No evento Click do boto Exit do form TryMySQL, codificar: 19) No evento Click do boto Exit do form Show Query, codificar: 20) No evento Close Query do form TryMySQL, codificar: 21) No evento Change do TComboBox cboDatabase do form TryMySQL,
codificar:
procedure TfrmTryMySQL.btnExitClick(Sender: TObject); procedure TfrmShowQuery.btnExitClick(Sender: TObject); procedure TfrmTryMySQL.FormCloseQuery(Sender: TObject; procedure TfrmTryMySQL.cboDatabaseChange(Sender: TObject);
begin begin var CanClose: boolean); begin
Close; Close; begin // Certifique-se de que s podemos selecionar um banco de dados,
end; end; // Sempre feche a conexo ao servidor de banco de dados! // se algum estiver selecionado no ComboBox.
// feito aqui porque, de qualquer modo que o form seja fechado, btnSelectDB.Enabled :=
// ele sempre chamado. (TComboBox(Sender).Items.Count > 0) and
mysql_close (mySQLSock); (TComboBox(Sender).ItemIndex <> -1);
CanClose := True; // Se no ha banco de dados (selecionado) nenhuma outra
end; // funcionalidade possivel.
// Vamos apagar toda informao j que ela no pode ser usada
// de qualquer modo.
if not btnSelectDB.Enabled then begin
btnOpenQuery.Enabled := False;
cboTable.Text := ;
cboTable.Items.Clear;
lstField.Clear;
end;
end;

47 48 49 50

Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto Desenvolver o Projeto


22) No evento Change do TComboBox cboTable do form TryMySQL, if (mysql_query (mySQLSock, PChar(stQuery)) < 0) 23) Salvar e executar o projeto.
then begin 24) Testar diferentes comandos MySQL.
codificar: ShowString (Requisicao de coluna falhou.+
procedure TfrmTryMySQL.cboTableChange(Sender: TObject); StrPas(mysql_error (mySQLSock))); Use vrios bancos diferentes.
var end else begin
stTable: String; fieldnamesBuffer := mysql_store_result (mySQLSock);
fieldnamesBuffer: PMYSQL_RES; try
stQuery: String; aField := mysql_fetch_row (fieldnamesBuffer);
aField: TMYSQL_ROW; while (aField <> nil) do begin
begin lstField.Items.Add(aField[0]);
lstField.Clear; aField := mysql_fetch_row (fieldnamesBuffer);
if cboTable.Text <> then begin end;
stTable := cboTable.Text; finally
// mysql_list_fields() nao funcionou no meu sistema e o mySQL mysql_free_result (fieldnamesBuffer);
// recomenda usar: end;
stQuery := SHOW COLUMNS FROM + stTable; end;
ShowString (Requisitando columas de: + stTable); end;
end;

continua ...
51 52 53

Desenvolver o Projeto Tarefas Executando o Projeto

25) Explicar cada linha de cdigo do projeto acima. Escrever cdigo para montar as queries baseadas nos campos Quando a aula terminar, clique no boto Play para ver o vdeo.
do banco de dados, sem a necessidade do usurio conhecer a
sintaxe dos comandos MySQL (uma caixa de dados para cada
campo).

Vous aimerez peut-être aussi