Avatar billede tuctoh Nybegynder
12. december 2003 - 17:32 Der er 11 kommentarer og
2 løsninger

Connecte til MYSQL database

Jeg skal koble en Query komponent op til en MYSQL database. Den database ligger på en server ude på nettet (har domænets navn). Lad os sige at den ligger på www.mydomain.com
Jeg har en user som skal kobles til:
username: usr1
password: pwd1
den lytter på port 3306

HVORDAN kobler jeg min query komponent op til den? Lige nu kører mit program med en lokal paradox database (don't laugh), men dette skal ændres til en "global" MYSQL db.

Burde være nemt, så håber på en hurtig løsning :)
Avatar billede morten_s Nybegynder
12. december 2003 - 18:05 #1
Jeg vil foreslå at du bruger dbExpress komponenterne som følger med til Delphi
de fungere fint til formålet og der kræves ingen installation af ODBC.. eller anden for for database engine
Avatar billede tuctoh Nybegynder
12. december 2003 - 18:12 #2
Ok, glemte at sige at det e Delphi 4 jeg har. Der er ikke nogen komponent som hedder dbExpress (jeg kan i hvert fald ikke finde den).
Avatar billede fixxxer Nybegynder
14. december 2003 - 15:53 #3
er det delphi 4 standard? i så fald skal du have fingrende i enten professinal eller enterprise for at kunne arbejde med database.
måske er der nogle 3. parts komponenter men de koster knapper
Avatar billede tuctoh Nybegynder
14. december 2003 - 19:51 #4
ved ikke om det er standard.. det er den version som fuldte med alt om data en gang for 3 år siden.
Men den har da database komponenter; arbejder med paradox database i den lige nu :p
Avatar billede koden12 Nybegynder
20. december 2003 - 02:19 #5
DBE findes på Delphi 4.

Det er dbExpress =  DBE

VH
koden12
Avatar billede tuctoh Nybegynder
20. december 2003 - 12:27 #6
jeg har ledt efter den komponent, men kan ikke finde den :s hvordan får jeg den frem?
Avatar billede koden12 Nybegynder
20. december 2003 - 13:00 #7
Er din Delphi 4 en uden database tools ?
Elles sættes de til ved at tilføje dem som Tools..

VH
koden12
Avatar billede tuctoh Nybegynder
20. december 2003 - 16:18 #8
Jeg har database tools i min menubjælke. Jeg har query komponent, tale, database, data source etc...
Data source ville jeg tro at jeg skal bruge, men hvor indtaster jeg IP, vælger my sql driver etc...?
Avatar billede koden12 Nybegynder
20. december 2003 - 20:41 #9
unit _libmysq;

{This is a more complete unit to interface with MySQL Server from Delphi
This work was started by by Blestan Tabakov. I have included the rest of the
functionality in libmysql.dll.
Delphi 3 Interface to LibMYSQL.dll
June 1998
Bob Silva  bsilva@umesd.k12.or.us

To find out more on this get the C API docs from www.tcx.se (makers of MySQL)}

{TODO: Implement as a VCL I dont think I have the knowledge to make it use Delphis
data controls but Ill look into it, I dont think the component will be too hard to
implement in the near future}


interface
const
mysql_errmsg_size=200;
MYSQL_PORT=3306;
LOCAL_HOST='localhost';
MYSQL_UNIX_ADDR='/tmp/mysql.sock';
NAME_LEN=64;
PROTOCOL_VERSION=10;
MYSQL_SERVER_VERSION='3.21.18-beta';
FRM_VER=6;
MYSQL_VERSION_ID=32115;
field_type_decimal=0;
field_type_tiny=1;
field_type_short=2;
field_type_long=3;
field_type_float=4;
field_type_double=5;
field_type_null=6;
field_type_timestamp=7;
field_type_longlong=8;
field_type_int24=9;
field_type_date=10;
field_type_time=11;
field_type_datetime=12;
field_type_enum=247;
field_type_set=248;
field_type_tiny_blob=249;
field_type_medium_blob=250;
field_type_long_blob=251;
field_type_blob=252;
field_type_var_string=253;
field_type_string=254;

type
enum_field_types=byte;
my_bool= shortint;
gptr= pchar;
socket= word;

mysql_status=(mysql_status_ready,mysql_status_get_result,mysql_status_use_result);

pused_mem=^used_mem;
used_mem=record
            next:pused_mem;
            left,size: Cardinal;
          end;

err_proc=procedure;

pmem_root=^mem_root;
mem_root=record
          free,used:pused_mem;
          min_malloc,block_size: Cardinal;
          error_handler:err_proc;
          end;

net=record
      fd: socket;
      fcntl: integer;
      buff,buff_end,write_pos: pchar;
      last_error:array[01..mysql_errmsg_size] of char;
      last_errno,max_packet,timeout,pkt_vnr: integer;
      error,return_errno: my_bool;
      end;

pmysql_field=^mysql_field;
mysql_field=record
            name,table,def: pchar;
            _type: enum_field_types;
            length,max_length,flags,decimals: Cardinal;
            end;
mysql_field_offset= Cardinal;

(*************HELP HERE IF YOU CAN*************)
{The C def for this is: typedef byte **MYSQL_ROW;
Blestan originally used the array struct below, but I could not get it to
work like that.
Blestan Code:  mysql_row=array[00..$ffff div sizeof(pchar)] of pchar;
My def of a smaller array seems to solve the problem, but if you were to return
a very large result set, Im sure it will AV. So if you can translate the C Code:
Earlier in code: typedef char      byte;
typedef byte **MYSQL_ROW; into an adequate Delphi type then please do and let
me know how you did it. I could get it to return rows using mysql_row: ^PChar; but
I couldnt figure out how to index into it like that.}



pmysql_row=^mysql_row;
mysql_row= array[00..$ff] of pchar;



(*********************************************)


pmysql_rows=^mysql_rows;
mysql_rows=record
            next: pmysql_rows;
            data: pmysql_row;
          end;
mysql_row_offset= pmysql_rows;

pmysql_data= ^mysql_data;
mysql_data= record
            rows, fields: Cardinal;
            data: pmysql_rows;
            alloc: mem_root;
            end;

pmysql=^mysql;
mysql= record
        _net: net;
        host,user,passwd,
        unix_socket,
        server_version,
        host_info,
        info,db: pchar;
        port,client_flag,server_capabilities,
        protocol_version,field_count: Cardinal;
        thread_id, affected_rows, insert_id, extra_info:longint;
        status: mysql_status;
        fields: pmysql_field;
        field_alloc: mem_root;
        free_me, reconnect: my_bool;
      end;

pmysql_res=^mysql_res;
mysql_res= record
          row_count: longint;
          field_count, current_field: Word;
          fields: pmysql_field;
          data: pmysql_data;
          data_cursor:pmysql_rows;
          field_alloc:mem_root;
          row: mysql_row;
          current_row: pmysql_row;
          lengths: ^Word;
          handle: ^mysql;
          eof: my_bool;
          end;

const thelib='libmysql.dll';
(*********ALL functions are working unless stated otherwise*************)
{If you can figure why why one of the ones marked bad is not working, please
send me the code to implement it properly}

function mysql_connect( _mysql: pmysql; const host,user,passwd:pchar):pmysql;stdcall;
{Non-functional: dont know why yet: I think you can do without it for now}
function mysql_real_connect(_mysql: pmysql; const host, user, passwd, db:pchar;
port:Cardinal; unix_socket:PChar;clientflag:Cardinal):pmysql;stdcall;
procedure mysql_close( _mysql: pmysql); stdcall;
function mysql_select_db(_mysql:pmysql;const DB: pchar):integer; stdcall;
function mysql_query(_mysql:pmysql;const query: pchar):integer;stdcall;
{Real Query not implemented in current version of libmysql.dll (timestamp:353be33a)}
function mysql_real_query(_mysql:pmysql;const query: pchar;length: Cardinal):integer;stdcall;
function mysql_create_db(_mysql:pmysql; const DB:PChar):integer;stdcall;
function mysql_drop_db(_mysql:pmysql; const DB:PChar):integer;stdcall;
function mysql_shutdown(_mysql: pmysql): Integer; stdcall;
{Although undocumented, I believe this is to reload the permissions table;
documentation calls for a reload function which there is none in libmysql.dll,
so I think this may be a replacement, it takes a Cardinal for options but I cant find out
what those options are since its not documented}
function mysql_refresh(_mysql:pmysql; refresh_options: Cardinal):integer;stdcall;
function mysql_kill(_mysql:pmysql; pid:longint):integer;stdcall;
function mysql_stat(_mysql:pmysql):pchar; stdcall;
function mysql_get_server_info(_mysql:pmysql):PChar;stdcall;
function mysql_get_client_info:PChar;stdcall;
function mysql_get_host_info(_mysql:pmysql):PChar;stdcall;
function mysql_get_proto_info(_mysql:pmysql):Cardinal;stdcall;
function mysql_list_dbs(_mysql:pmysql;wild: pchar):pmysql_res; stdcall;
function mysql_list_tables(_mysql: pmysql; const wild: pchar):pmysql_res; stdcall;
function mysql_list_fields(_mysql: pmysql;const table,wild: pchar):pmysql_res; stdcall;
function mysql_list_processes(_mysql: pmysql):pmysql_res; stdcall;
function mysql_store_result(_mysql:pmysql):pmysql_res; stdcall;
function mysql_use_result(_mysql:pmysql):pmysql_res;stdcall;
procedure mysql_free_result(result:pmysql_res); stdcall;
procedure mysql_data_seek(result:pmysql_res; offset:Cardinal); stdcall;
{Row seek is probably functional if I knew how to test it;
I think its a matter of saving a particular row pointer in a mysql_row_offset struct;
then later make a call to row_seek to restore the data_cursor to that row;
then a fetch_row will return the next row after that???? I have no need for it so you tell me}
function mysql_row_seek(result:pmysql_res; row:mysql_row_offset):mysql_row_offset;stdcall;
{Field Seek is not implemented in current version of libmysql.dll(timestamp:353be33a)}
function mysql_field_seek(result:pmysql_res;offset:mysql_field_offset):mysql_field_offset;stdcall
function mysql_fetch_row(result:pmysql_res):pmysql_row;stdcall;
{I dont think fetch_length is working properly because of the way that I set up the MYSQL_ROW array}
function mysql_fetch_lengths(result:pmysql_res):Cardinal;stdcall;
function mysql_fetch_field(handle: pmysql_res):pmysql_field; stdcall;

implementation
function mysql_connect( _mysql: pmysql; const host,user,passwd:pchar):pmysql;stdcall;external thelib;
function mysql_real_connect(_mysql: pmysql; const host, user, passwd, db:pchar;
port:Cardinal; unix_socket:PChar;clientflag:Cardinal):pmysql;stdcall;external thelib;
procedure mysql_close( _mysql: pmysql); stdcall;external thelib;
function mysql_select_db(_mysql:pmysql;const DB: pchar):integer; stdcall;external thelib;
function mysql_query(_mysql:pmysql;const query: pchar):integer;stdcall;external thelib;
function mysql_real_query(_mysql:pmysql;const query: pchar;length: Cardinal):integer;stdcall;external thelib;
function mysql_create_db(_mysql:pmysql; const DB:PChar):integer;stdcall;external thelib;
function mysql_drop_db(_mysql:pmysql; const DB:PChar):integer;stdcall;external thelib;
function mysql_shutdown(_mysql: pmysql): Integer; stdcall;external thelib;
function mysql_refresh(_mysql:pmysql; refresh_options: Cardinal):integer;stdcall;external thelib;
function mysql_kill(_mysql:pmysql; pid:longint):integer;stdcall;external thelib;
function mysql_stat(_mysql:pmysql):pchar; stdcall;external thelib;
function mysql_get_server_info(_mysql:pmysql):PChar;stdcall;external thelib;
function mysql_get_client_info:PChar;stdcall;external thelib;
function mysql_get_host_info(_mysql:pmysql):PChar;stdcall;external thelib;
function mysql_get_proto_info(_mysql:pmysql):Cardinal;stdcall;external thelib;
function mysql_list_dbs(_mysql:pmysql;wild: pchar):pmysql_res; stdcall;external thelib;
function mysql_list_tables(_mysql: pmysql; const wild: pchar):pmysql_res; stdcall;external thelib;
function mysql_list_fields(_mysql: pmysql;const table,wild: pchar):pmysql_res; stdcall;external thelib;
function mysql_list_processes(_mysql: pmysql):pmysql_res; stdcall;external thelib;
function mysql_store_result(_mysql:pmysql):pmysql_res; stdcall;external thelib;
function mysql_use_result(_mysql:pmysql):pmysql_res;stdcall;external thelib;
procedure mysql_free_result(result:pmysql_res); stdcall;external thelib;
procedure mysql_data_seek(result:pmysql_res; offset:Cardinal); stdcall;external thelib;
function mysql_row_seek(result:pmysql_res; row:mysql_row_offset):mysql_row_offset;stdcall;external thelib;
function mysql_field_seek(result:pmysql_res;offset:mysql_field_offset):mysql_field_offset;stdcall;external thelib;
function mysql_fetch_row(result:pmysql_res):pmysql_row;stdcall;external thelib;
function mysql_fetch_lengths(result:pmysql_res):Cardinal;stdcall;external thelib;
function mysql_fetch_field(handle: pmysql_res):pmysql_field; stdcall;external thelib;

end.


og selve programmet :

unit connect;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, _libmysq;

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    edtHostname: TEdit;
    edtUsername: TEdit;
    edtPasswd: TEdit;
    edtDatabase: TEdit;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button3Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  mysqlrec: mysql; //Global mysql struct
  connected: Integer; //Global var to keep track of whether we are connected
implementation

{$R *.DFM}

procedure TForm1.Button3Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    if connected = 1 then
    {Close the Database Connection}
    mysql_close(@mysqlrec);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  host, user, passwd: String;

begin
    host:= edtHostname.Text;
    user:= edtUsername.Text;
    passwd:= edtPasswd.Text;
    {Connect to server}
    mysql_connect(@mysqlrec, PChar(host), PChar(user), PChar(passwd));
    if mysqlrec.status = mysql_status_ready then
    begin
          ShowMessage ('Successfully connected to the Database.');
          connected:= 1; //keep track of connection
          Button2.Enabled:= true;
          Button4.Enabled:= true;
          Button1.Enabled:= false;
    end
    else
        ShowMessage ('Unable to connect to database.');
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  db: String;
  retval: Integer;
begin
    db:= edtDatabase.Text;
    retval:= mysql_select_db(@mysqlrec, PChar(db));
    if retval <> 0 then
        ShowMessage('Error attaching to: ' + db)
    else
        ShowMessage('Successfully attached to ' + db);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    mysql_close(@mysqlrec);
    ShowMessage('Disconnected from the database.');
    Button1.Enabled:= true;
    Button2.Enabled:= false;
    Button4.Enabled:= false;
    connected:= 0;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    connected:= 0; //We are not connected to the server
    {Disable the disconnect button till connected}
    Button2.Enabled:= false;
    {Disable the attach to db button till connected}
    Button4.Enabled:= false;
end;

end.



koden12
Avatar billede tuctoh Nybegynder
20. december 2003 - 21:05 #10
jeg har INGEN anelse om hvad jeg skal gøre med den kode :s Jeg er ret ny i delphi.
Hvor taster jeg det ind, og hvordan fyrer jeg en ganske normal SQL sæt af imod den?
Jeg har før bare brugt en query komponent, til paradox databaser... hvad er forskellen på metoden ved de to komponenter?
Avatar billede koden12 Nybegynder
20. december 2003 - 22:11 #11
Start med noget let så..
Din udbyder må have skrevet hvordan du gør..

VH
koden12
Avatar billede tuctoh Nybegynder
20. december 2003 - 23:35 #12
jeg har styr på databaser etc... bare ikke delphi. Det er en ven som har sat en database op jeg kan bruge.
Kan man ikke på en simpel måde sætte sin query komponent til at pege på en mySQL database, som man gør det til en paradox db?
Avatar billede koden12 Nybegynder
20. december 2003 - 23:44 #13
Nej ikke mig bekendt..
Og ikke med en Delphi 4.
Man kan heller ikke blande æbler og bananer.
Køb nogle Delphi bøger.

VH
koden12
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