Este é um artigo que visa demostrar como podemos usar a linguagem C para realizar as ações básicas em um banco de dados MySQL. As ações básicas num banco de dados são: inserção, remoção, alteração e consulta de dados.
Para desenvolver um programa de consulta num banco de dados MySQL iremos
introduzir mais quatro funções:
unsigned int mysql_num_fields(MYSQL_RES *res);
MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES *res);
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
void mysql_free_result(MYSQL_RES *result);
Vamos começar falando da primeira função, ela serve para sabermos quantos
campos existem na tabela em que foi feita a "query". A estrutura que ela
recebe como parâmetro é a retornada por mysql_store_result.
A função seguinte (mysql_fetch_fields) tem como retorno uma estrutura
que é um array. Essa estrutura possui alguns dados muito úteis, como o nome da
coluna.
A mysql_fetch_row retorna os registros encontrados e como cada registro
tem várias colunas o valor char que é retornado é um vetor sendo que cada
"posição" corresponde a uma coluna da tabela.
Por fim, a que resta ser explicada (mysql_free_result) serve para
limpar a variável de resultado retornado por mysql_store_result.
Vejamos, um exemplo para consultar com as funções citadas.
#include <stdio.h>
#include <mysql/mysql.h>
#define HOST "localhost"
#define USER "guest"
#define PASS "guest"
#define DB "teste"
int main(void)
{
MYSQL conexao;
MYSQL_RES *resp;
MYSQL_ROW linhas;
MYSQL_FIELD *campos;
char query[]="SELECT * FROM aprendendo;";
int conta; //Contador comum
mysql_init(&conexao);
if (mysql_real_connect(&conexao,HOST,USER,PASS,DB,0,NULL,0))
{
printf("Conectado com Sucesso!\n");
if (mysql_query(&conexao,query))
printf("Erro: %s\n",mysql_error(&conexao));
else
{
resp = mysql_store_result(&conexao);//recebe a consulta
if (resp) //se houver consulta
{
//passa os dados dos campos para a variável campos
//escreve na tela os nomes dos campos dando
//um tab somente
campos = mysql_fetch_fields(resp);
for (conta=0;conta<mysql_num_fields(resp);conta++) {
printf("%s",(campos[conta]).name);
if (mysql_num_fields(resp)>1)
printf("\t");
}
printf("\n");
//enquanto retonrnar registros, conta até o
//número de colunas que a tabela tem e escreve na
//tela com um tab, depois pula a linha e tenta
//pegar outro registro
while ((linhas=mysql_fetch_row(resp)) != NULL)
{
for (conta=0;conta<mysql_num_fields(resp);conta++)
printf("%s\t",linhas[conta]);
printf("\n");
}
}
mysql_free_result(resp);//limpa a variável do resultado: resp
}
mysql_close(&conexao);
}
else
{
printf("Conexao Falhou\n");
if (mysql_errno(&conexao))
printf("Erro %d : %s\n", mysql_errno(&conexao), mysql_error(&conexao));
}
return 0;
}
Nesse programa podemos ver um exemplo que considero básico de consulta. Nele
também temos macros para facilitar mudar, por exemplo, o servidor de conexão
do MySQL. Execute o programa e você deverá ver algo como:
$ ./a.out
Conectado com Sucesso!
ID nome sexo
1 Ricardo Rodrigues Lucca M
[7] Comentário enviado por jllucca em 30/08/2004 - 13:43h
Apenas pra completar, ao invés de utilizar um falor predefinido ali e sempre constante nas querys podemos criar um ponteiro para char e usar ele para montar uma query usando variaveis do proprio programa.
[11] Comentário enviado por jllucca em 05/01/2005 - 19:44h
Site que explique conheço um que explica a mesma coisa so q em ingles. Livro tem um chamado Linux Professional muito bom, não só pra esse assunto como para outros...
[12] Comentário enviado por Biudi em 10/01/2005 - 11:51h
Muito bom esse seu artigo! Me ajudou bastante...estou iniciando com Linux(Conectiva 10) e tô com problemas no MySQL, encontro o seguinte erro:"checking for mysql_init in -lmysqlclient...no", tô sem saber onde encontrar esse pacote,alguém poderia por favor me ajudar?
[13] Comentário enviado por fabiocosta em 25/01/2005 - 12:16h
ae galera, achei muito interessante este artigo, mas fiquei com uma dúvida que ao longo do texto não consegui tirar. Como executar um código-fonte desses de conexão com mysql se eu ao menos vi uma biblioteca para isso, que no caso seria "<stdio.h>" e "<mysql/mysql.h>", enfim, gostaria de saber como faria pra acessar o mysql, como faria para possuir as bibliotecas.
[15] Comentário enviado por removido em 20/06/2006 - 12:08h
eu baixei o MySQL e tentei instalar no meu laptop, mas não consegui por causa de um bloqueio da Fontes de dados (ODBC). Como faço prá resolver isso ? E caso eu use o SQL Professional Edition, dá prá criar o mesmo programa nele? Qual modificação eu preciso fazer?
Valeu!!
[17] Comentário enviado por hartax em 02/08/2006 - 00:55h
um amigo meu resolveu o meu prob com as variaveis hj ai entro aqui pra ver se alguem tinha respondido e o marrento me manda o que esse meu amigo me mandou hahaha valeuz marrento!
[19] Comentário enviado por lufagovi em 02/12/2006 - 03:48h
eu tentei compilar varias vezes, mas só me da os seguintes erros...
C:\MinGW\include\mysql\mysql_com.h:175: error: `SOCKET' does not name a type
C:\MinGW\include\mysql\mysql_com.h:339: error: `SOCKET' was not declared in this scope
C:\MinGW\include\mysql\mysql_com.h:339: error: expected primary-expression before "const"
C:\MinGW\include\mysql\mysql_com.h:339: error: expected primary-expression before "unsigned"
C:\MinGW\include\mysql\mysql_com.h:340: error: expected primary-expression before "unsigned"
C:\MinGW\include\mysql\mysql_com.h:340: error: initializer expression list treated as compound expression
:: === Build finished: 6 errors, 0 warnings ===
Será que alguem pode me ajudar?
[25] Comentário enviado por netmorais em 18/06/2008 - 13:48h
Ricardo
Sou novato em MySql. Li o seu artigo achei muito bom. Testei nu Linux e correu tudo bem. Resolvi fazer um teste análogo no Windows utilizando um de seus exemplos e estou encontrando problemas. Veja a seguir:
com Gcc do MinGW, MySQL 5.0 e a pasta .../mysql/* em /mingw/include/mysql ocorrem os seguintes erros durante a complilação:
$ gcc teste.c -l mysqlclient
In file included from /mingw/include/mysql/mysql.h:72, from teste.c:2:
/mingw/include/mysql/mysql_com.h:183: parse error before "SOCKET"
/mingw/include/mysql/mysql_com.h:222: parse error before '}' token
/mingw/include/mysql/mysql_com.h:335: parse error before '*' token
/mingw/include/mysql/mysql_com.h:336: parse error before '*' token
/mingw/include/mysql/mysql_com.h:337: parse error before '*' token
/mingw/include/mysql/mysql_com.h:338: parse error before '*' token
/mingw/include/mysql/mysql_com.h:339: parse error before '*' token
/mingw/include/mysql/mysql_com.h:340: parse error before '*' token
.....
[26] Comentário enviado por netmorais em 18/06/2008 - 16:26h
Ricardo
Já diminuiu os erros. Usei o include sugerido "windows.h" mas continua aparecendo:
\mingw\lib\gcc-lib\mingw32\3.2.3\..\..\..\..\mingw32\bin\ld.exe: cannot find -lmysqlclient
Usei a opção -L .../MySQL/.../lib/opt, copiei o .../MySQL/.../lib/opt para mas não funciona.
Sérgio.
netmorais@ig.com.br
[27] Comentário enviado por wgaprendiz em 12/10/2008 - 23:12h
Ola Ricardo
Muito bom seu artigo.
Bom estou com alguns problemas para executar os exemplos.
Utilizo a versão 4.9.9.2 do Dev c/c++ no win XP Pro.
Ja baixei a bilbioteca mysql.h
Ao tentar compilar os exemplos , aparecem as seguintes mensagens de erro no dev:
[Linker error] undefined reference to 'WinMain@16'
Id returned 1 exit status
C:\Dev-Cpp\Makefile.win [Build Error] [project2.exe] Error 1
Como sou novato em C não sei decifrar esses erros , mas acho que o problema possa estar na biblioteca mysql.h, pois eu baixei a primeira que encontrei e nao sei se é a mais adequada.
[28] Comentário enviado por abekawa em 01/04/2009 - 21:43h
Olá Pessoal,
No linux a biblioteca libmysql pode ser instalada baixando o pacote libmysql++-dev .
Distribuições baseadas em debiam podem usar o seguinte comando.
#sudo apt-get install libmysql++-dev
Tambem deverá ser feito algumas alterações no código:
declarem a main como int, como nosso amigo lá em cima já citou.
[30] Comentário enviado por netmorais em 17/06/2009 - 10:47h
Ricardo
Usei o modelo do seu artigo para construir um executavel tanto no Linux, como no Windows (.exe, infelizmente preciso) para estabelecer a conexão a baixo custo de outras linguagens com o Mysql e funciona muito bem. A biblioteca que uso na compilação com o gcc é a libmysqlclient.a que vem junto com a distribuição do Mysql.
Atualmente, no caso do Windows, estou tentando melhorar a performance da interface criando uma Dll. Para isso transformei o programa em C em um conjunto de "funções" para conexão, execução de sqls e desconexão com banco. Aplicação que "chama" as funções é pre-compilada em um .obj, assim como as "funções" que acessam o banco com "gcc -c funcoes.c -o funcoes.obj". (não posso "linkar" o Mysql nesse momento). Após isso executo o Link (da MS) "link ... -d aplicacao.obj funcoes.obj libmysqlclient.a" que cria a Dll e naõ aponta nenhum erro. Porém na execução aborta logo no "mysql_init".
A biblioteca "libmysqlcliente.a" utilizada não é apropriada para este caso? Existe "mysqlclient.obj"?
Grato
Sérgio.
[32] Comentário enviado por walquiriosaraiva em 20/11/2009 - 06:54h
Bom dia pessoal!!
Estou com um problema em C, não consigo encontrar a biblioteca para conexão com banco de dados. Não sei onde baixar, já tentei encontrar mais as que achei não funciona quando eu tento compilar o programa ele dá um erro e pelo que percebi deve ser na biblioteca.
[33] Comentário enviado por Raios em 16/04/2010 - 15:56h
Olá pessoal bem a conexão foi realizada com sucesso só que na hora de eu transformar isso tudo para DLL, gera um erro na conexão, bem esse é meu código porém não consigo criar uma DLL com banco. Gostaria que me ajudasse.
int main(void)
{
MYSQL conexao;
MYSQL_RES *resp;
MYSQL_ROW linhas;
MYSQL_FIELD *campos;
char query[]="SELECT * FROM cliente;";
int conta; //Contador comum
mysql_init(&conexao);
if (mysql_real_connect(&conexao,"localhost","user","user","dados",0,NULL,0))
{
printf("Conectado com Sucesso!\n");
if (mysql_query(&conexao,query))
printf("Erro: %s\n",mysql_error(&conexao));
else
{
resp = mysql_store_result(&conexao);//recebe a consulta
if (resp) //se houver consulta
{
//passa os dados dos campos para a vari·vel campos
//escreve na tela os nomes dos campos dando
//um tab somente
campos = mysql_fetch_fields(resp);
for (conta=0;conta<mysql_num_fields(resp);conta++) {
printf("%s",(campos[conta]).name);
if (mysql_num_fields(resp)>1)
printf("\t");
}
printf("\n");
//enquanto retonrnar registros, conta atÈ o
//n˙mero de colunas que a tabela tem e escreve na
//tela com um tab, depois pula a linha e tenta
//pegar outro registro
while ((linhas=mysql_fetch_row(resp)) != NULL)
{
for (conta=0;conta<mysql_num_fields(resp);conta++)
printf("%s\t",linhas[conta]);
printf("\n");
}
}
mysql_free_result(resp);//limpa a vari·vel do resultado: resp
}
mysql_close(&conexao);
}
else
{
printf("Conexao Falhou\n");
if (mysql_errno(&conexao))
printf("Erro %d : %s\n", mysql_errno(&conexao), mysql_error(&conexao));
}
system("pause");
return 0;
}
[34] Comentário enviado por wcoutinho em 22/04/2010 - 01:56h
muito bom o post.
eu to com uma serie de problemas na compilacao.
gcc mysql-connect.c -lmysqlclient
mysql-connect.c:2:24: error: mysql/mysql.h: No such file or directory
mysql-connect.c: In function ‘main’:
mysql-connect.c:11: error: ‘MYSQL’ undeclared (first use in this function)
mysql-connect.c:11: error: (Each undeclared identifier is reported only once
mysql-connect.c:11: error: for each function it appears in.)
mysql-connect.c:11: error: expected ‘;’ before ‘conexao’
mysql-connect.c:12: error: ‘MYSQL_RES’ undeclared (first use in this function)
mysql-connect.c:12: error: ‘resp’ undeclared (first use in this function)
mysql-connect.c:13: error: ‘MYSQL_ROW’ undeclared (first use in this function)
mysql-connect.c:13: error: expected ‘;’ before ‘linhas’
mysql-connect.c:14: error: ‘MYSQL_FIELD’ undeclared (first use in this function)
mysql-connect.c:14: error: ‘campos’ undeclared (first use in this function)
mysql-connect.c:18: error: ‘conexao’ undeclared (first use in this function)
mysql-connect.c:23: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
mysql-connect.c:45: error: ‘linhas’ undeclared (first use in this function)
mysql-connect.c:60: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘int’
[36] Comentário enviado por williandiniz em 03/07/2010 - 16:00h
resposta ao [7] Comentário enviado por jllucca em 30/08/2004 - 13:43h:
Complementado:
int res;
int data=999;
int lat=1000;
char* query[100];
sprintf(query,"INSERT INTO dados_teste (ID,lati) values ('%d','%d');",data,lat);
.
.
.
res = mysql_query(&conexao,query);
dados_teste = nome da tabela
ID e lati são os campos da tabela
data e lat são as variaveis.
[41] Comentário enviado por jairjunior em 29/08/2014 - 16:13h
Engraçado no debian para conseguir rodar algum aplicativo usando a mysql.h só consegui após ter configurado o conector tudo direitinho e tal estava tentando usar a linha de comando:
# gcc teste-mysql -lmysql -o testemysql.exe
e não estava funcionando troquei pela:
# gcc `mysql_config --cflags --include --libs` teste-mysql.c -o teste-mysql.exe
funcionou beleza.
Ja no Windows 7 é justamente o contrario só funciona com o comando:
# gcc teste-mysql -lmysql -o testemysql.exe
E outra coisa só funcionou após eu mudar o #include
que estava #include<mysql/mysql.h> como nos exemplos deste site troquei por
#include<mysql.h>