Avatar billede nomak Nybegynder
16. april 2003 - 02:50 Der er 23 kommentarer og
1 løsning

MySQL i C program på en unix box..

Hej E!

Jeg har efter en masse mislykkede forsøg, opgivet selv af finde ud af hvordan man henter data fra en MySQL database..

Det jeg søger er en source/tutorial om hvordan man kan gøre dette..

HUSK det SKAL være i C og IKKE C++!

På forhånd tak
/NoMak
Avatar billede a_eriksen Nybegynder
16. april 2003 - 05:18 #1
Der er glimrende eksempler at finde hos mysql.com
Kig i manualen i kapitel 8
Avatar billede arne_v Ekspert
16. april 2003 - 08:11 #2
Jeg lavede et lille eksempel på brug af ODBC fra C++ igår.

Det er nemt at konvertere til C:

#include <stdio.h>
#include <stdlib.h>

#include <windows.h>
#include <sql.h>
#include <sqlext.h>

char* dsn = "TestMSAccess";
char* un = "";
char* pw = "";
char* sqlstr = "SELECT * FROM T1";

int main(int argc, char *argv[])
{
  SQLHENV Environment;
  SQLHDBC DataBaseConnect;
  SQLHSTMT stmt;
  SQLRETURN stat;
  int i,il,sl;
  char s[10];
  stat = SQLAllocEnv(&Environment);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocEnv\n");
  stat = SQLAllocConnect(Environment,&DataBaseConnect);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocConnect\n");
  stat = SQLConnect(DataBaseConnect,
                    (SQLCHAR *)dsn,strlen(dsn),
                    (SQLCHAR *)un,strlen(un),
                    (SQLCHAR *)pw,strlen(pw));
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in Connect\n");
  stat = SQLAllocStmt(DataBaseConnect,&stmt);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocStmt\n");
  stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr));
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in ExecDirect\n");
  stat = SQLBindCol(stmt,1,SQL_C_LONG,&i,sizeof(i),(SQLINTEGER *)&il);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in BindCol\n");
  stat = SQLBindCol(stmt,2,SQL_C_CHAR,s,sizeof(s),(SQLINTEGER *)&sl);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in BindCol\n");
  for(;;) {
    stat = SQLFetch(stmt);
    if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) break;
    s[sl] = '\0';
    printf("%d %s\n",i,s);
  }
  SQLFreeStmt(stmt,SQL_DROP);
  SQLDisconnect(DataBaseConnect);
  SQLFreeConnect(DataBaseConnect);
  SQLFreeEnv(Environment); 
  return 0;
}
Avatar billede arne_v Ekspert
16. april 2003 - 08:12 #3
T1 har 2 felter: et integer og et text.
Avatar billede nomak Nybegynder
16. april 2003 - 14:27 #4
arne_v: Det fattede jeg så hat af.. Det skulle jo ikke være i C++ :(
Avatar billede arne_v Ekspert
16. april 2003 - 14:30 #5
Ovenstående er valid C.

Hvad mener du der ikke skule compile med C ?
Avatar billede arne_v Ekspert
16. april 2003 - 14:30 #6
Det burde faktisk være rimeligt til at forstå.

Du kan evt. slette alle testene på status for at gøre det lidt nemmere
at overskue.
Avatar billede nomak Nybegynder
17. april 2003 - 12:55 #7
Okay, jeg har nu flg. kode.. men får en compiling error..

#include "/usr/local/include/mysql/mysql.h"
#include <stdio.h>


int main(void) {
    MYSQL* mysql_handle = mysql_init(NULL);
    MYSQL_RES *result;
    MYSQL_ROW row;

    int num_fields;
    int i;
   
    if(mysql_handle == NULL)
    {
        printf("MySQL error: %s", mysql_error(mysql_handle));
        exit(1);
    }

    if(!mysql_real_connect(mysql_handle, "localhost", "****", "********", "MyDatabase", 0, NULL, 0))
    {
        printf("MySQL error: %s", mysql_error(mysql_handle));
        exit(1);
    }

    mysql_query(mysql_handle, "SELECT nick, pass FROM users");

    result = mysql_store_result(mysql_handle);
    num_fields = mysql_num_fields(result);

    while ((row == mysql_fetch_row(result))) {

        unsigned long *lengths;
        lengths = mysql_fetch_lengths(result);

        for (i=0; i<num_fields; i++) {
            printf("[%.*s]", (int) lengths[i], row[i] ? row[i] : "NULL");
        }
        printf("\n");

    }

    mysql_free_result(result);   
    mysql_close(mysql_handle);

    return 1;
}

men får flg. fejl...

-bash-2.05b$ cc -o a a.c
/tmp/ccpuyrOc.o: In function `main':
/tmp/ccpuyrOc.o(.text+0xc): undefined reference to `mysql_init'
/tmp/ccpuyrOc.o(.text+0x29): undefined reference to `mysql_error'
/tmp/ccpuyrOc.o(.text+0x6f): undefined reference to `mysql_real_connect'
/tmp/ccpuyrOc.o(.text+0x87): undefined reference to `mysql_error'
/tmp/ccpuyrOc.o(.text+0xb9): undefined reference to `mysql_query'
/tmp/ccpuyrOc.o(.text+0xc8): undefined reference to `mysql_store_result'
/tmp/ccpuyrOc.o(.text+0xdc): undefined reference to `mysql_num_fields'
/tmp/ccpuyrOc.o(.text+0xf0): undefined reference to `mysql_fetch_row'
/tmp/ccpuyrOc.o(.text+0x10c): undefined reference to `mysql_fetch_lengths'
/tmp/ccpuyrOc.o(.text+0x19c): undefined reference to `mysql_free_result'
/tmp/ccpuyrOc.o(.text+0x1ab): undefined reference to `mysql_close'
Avatar billede arne_v Ekspert
17. april 2003 - 13:01 #8
Du skal linke mod libmysql og/eller mysqlclient.

Prøv med noget i retning af:

cc -o a a.c /somewhere/libmysql.a /somewhere/mysqlclient.a
Avatar billede nomak Nybegynder
17. april 2003 - 13:21 #9
-bash-2.05b$ cc -o a a.c /usr/local/lib/mysql/libmysqlclient.a
/usr/local/lib/mysql/libmysqlclient.a(password.o): In function `scramble':
password.o(.text+0x288): undefined reference to `floor'
password.o(.text+0x2dd): undefined reference to `floor'
/usr/local/lib/mysql/libmysqlclient.a(password.o): In function `check_scramble':
password.o(.text+0x39c): undefined reference to `floor'
password.o(.text+0x3fc): undefined reference to `floor'
/usr/local/lib/mysql/libmysqlclient.a(my_compress.o): In function `my_compress_alloc':
my_compress.o(.text+0xb0): undefined reference to `compress'
/usr/local/lib/mysql/libmysqlclient.a(my_compress.o): In function `my_uncompress':
my_compress.o(.text+0x121): undefined reference to `uncompress'
Avatar billede arne_v Ekspert
17. april 2003 - 13:25 #10
Prøv og se hvad der ellers er af .a filer i /usr/local/lib/mysql !

Hvis der er en en zlib.a, så bør:

cc -o a a.c /usr/local/lib/mysql/libmysqlclient.a /usr/local/lib/mysql/zlib.a

kunne fjerne xompress/uncompres fejlene.
Avatar billede nomak Nybegynder
17. april 2003 - 13:28 #11
libdbug.a              libmyisammrg.a          libmystrings.a
libheap.a              libmysqlclient.a        libmysys.a
libmerge.a              libmysqlclient.so      libnisam.a
libmyisam.a            libmysqlclient.so.10

det er hvad der er i det lib..
Avatar billede arne_v Ekspert
17. april 2003 - 13:36 #12
Prøv og se om floor forsvinder med:

cc -o a -lm a.c /usr/local/lib/mysql/libmysqlclient.a

(-lm er ny)
Avatar billede nomak Nybegynder
17. april 2003 - 13:40 #13
det gjorde den :)

men der er stadig nogle fejl..

-bash-2.05b$ cc -o a -lm a.c /usr/local/lib/mysql/libmysqlclient.a
/usr/local/lib/mysql/libmysqlclient.a(my_compress.o): In function `my_compress_a
lloc':
my_compress.o(.text+0xb0): undefined reference to `compress'
/usr/local/lib/mysql/libmysqlclient.a(my_compress.o): In function `my_uncompress
':
my_compress.o(.text+0x121): undefined reference to `uncompress'
Avatar billede arne_v Ekspert
17. april 2003 - 13:43 #14
De funktioner er i zlib.a

Prøv og lav en:

find / -name zlib.a

og find ud af hvor den ligger og så put /wherever/zlib.a med i kommandoen.
Avatar billede nomak Nybegynder
17. april 2003 - 13:48 #15
/usr/ports/lang/php4/work/php-4.2.3/ext/zlib/.libs/libzlib.a <- kan den bruges?
Avatar billede arne_v Ekspert
17. april 2003 - 13:50 #16
Det vil jeg tro.

Prøv !

:-)
Avatar billede nomak Nybegynder
17. april 2003 - 13:51 #17
åbenbart ikke...

-bash-2.05b$ cc -o a -lm a.c /usr/local/lib/mysql/libmysqlclient.a /usr/ports/lang/php4/work/php-4.2.3/ext/zlib/.libs/libzlib.a
/usr/local/lib/mysql/libmysqlclient.a(my_compress.o): In function `my_compress_alloc':
my_compress.o(.text+0xb0): undefined reference to `compress'
/usr/local/lib/mysql/libmysqlclient.a(my_compress.o): In function `my_uncompress':
my_compress.o(.text+0x121): undefined reference to `uncompress'
Avatar billede arne_v Ekspert
17. april 2003 - 13:56 #18
Hvad sker der med:

cc -o a -lm -lz a.c /usr/local/lib/mysql/libmysqlclient.a

?

(-lz er ny)
Avatar billede nomak Nybegynder
17. april 2003 - 13:57 #19
hmm... det virker? :D
Avatar billede arne_v Ekspert
17. april 2003 - 13:59 #20
Kan:

find / -name zlib.so

finde noget ?

[ja - jeg gætter mig lidt frem]
Avatar billede arne_v Ekspert
17. april 2003 - 13:59 #21
Det virkede ????

OK - så kan du jo rask gå videre til næste problem !

:-)
Avatar billede nomak Nybegynder
17. april 2003 - 14:01 #22
YiR, og næste problem er at den ikke spytter noget output ud.. selvom der er noget i tabellen? :(
Avatar billede arne_v Ekspert
17. april 2003 - 14:07 #23
Jeg er ret sikker på at du mener:

while ((row = mysql_fetch_row(result))) {

og ikke:

while ((row == mysql_fetch_row(result))) {

[kun et ligheds tegn]
Avatar billede nomak Nybegynder
17. april 2003 - 14:38 #24
Woohoo :D Takker arne!

points til dig :P
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester