全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:12974
推到 Plurk!
推到 Facebook!

如何在 BCB 5.0 使用 MySQL C API 連線 mysqld (在 FreeBSD 上)

 
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-07-03 19:00:40 IP:125.231.xxx.xxx 未訂閱
閒著沒事寫寫文章好了。
首先,灌一台 FreeBSD, 然後用它的 ports 下面的 mysql 去 make; make install 把它裝好。
並且啟動它。這些動作不在這篇的討論範圍。
再來到 www.mysql.com 去下載 mysql 回來安裝。沒錯,在你的 windows XP 上裝入 mysql server
這個動作也請參考 mysql 的說明。
至於,這樣做之後 XP 上就會有 mysql 了呀。我為什麼要教大家連 FreeBSD 呢?
理由是local XP 的 MySQL 只是讓你測試開發的。我不建議你真的用它來負載重一點的事。
只是程式寫起來是一樣的。

好吧。裝好了吧。
找找看你的 mysql 裝在那邊
看一下它的目錄下面有沒有一個 \lib\debug
這個目錄下面有個 libmysql.dll
這個是我們的目標之一。簡稱目標A(A)
我們開個 dos session 來做些事。
implib t.lib libmysql.dll
這一招可以把 libmysql.dll 變成我們能用的 lib.
就不用去做 load..... 那種煩人的動作了。
再來我們開一支空的程式。
在 project -> add to project 把這個 t.lib 加到我們的 project 裏面。

在前面打下 #include "c:\mysql\include\mysql.h" (假設你把 mysql 裝在 c:\mysql)
在你的 form1 放上兩個元件
button1
stringgrid1
在 button1click 裏寫上
MYSQL mysql;
MYSQL_RES *res;
MYSQL_ROW row;
mysql_init(&mysql);
mysql_real_connect(&mysql, HOST, USER, PWD, DBNAME, 0, NULL, 0);
mysql_query(&mysql, "SELECT * FROM tablename");
int j = 0;
while ((row = mysql_fetch_row(res)) != NULL)
{
StringGrid1->RowCount = j 1;
StringGrid1->Cells[0][j] = row[0];
StringGrid1->Cells[1][j] = row[1];
j ;
}
mysql_free_result(res);
mysql_close(&mysql);

然後就可以存當,執行。
當然,在這之前,你要先設定好你的 sql server 的 host, id, pwd, dbname, tablename,......這個不在這篇要說的。
然後你就可以執行了。

當然,當你想要把你的程式丟給別人時。記得要把目標(A)一起CO給他。
就可以了。
只要你放在跟你的執行檔相同地方就可以了。
當然也可以放到什麼 system32....etc 下面。讓WINDOWS可以找到就好。

這個算是它的基本操作。
如果有什麼問題,可以把 MySQL 的手冊拿起來查查它的 C API 的使用法。

以上,請勿轉載。謝謝。
river_l
一般會員


發表:4
回覆:9
積分:2
註冊:2007-04-26

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-05-09 18:17:25 IP:220.141.xxx.xxx 訂閱
請教一下 您在實做時是否有遇到以下問題 如果有或者您知道如何解決 可否請您告知 謝謝


暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-05-10 22:19:52 IP:122.118.xxx.xxx 未訂閱
先 #include <windows.h>
再 #include "mysql.h"
其它的都一樣.
===================引 用 river_l 文 章===================
請教一下 您在實做時是否有遇到以下問題 如果有或者您知道如何解決 可否請您告知 謝謝


river_l
一般會員


發表:4
回覆:9
積分:2
註冊:2007-04-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-05-13 08:29:07 IP:220.141.xxx.xxx 訂閱
您好,

我將 mysql.h放在最後 include, 仍有以下問題, 可否再請教您如何解決此問題, 非常感謝您的幫忙

#ifndef Unit1H
#define Unit1H
#include
#include
#include
#include
#include
#include
#include
#include

#include


===================引 用 暗黑破壞神 文 章===================
先 #include
再 #include "mysql.h"
其它的都一樣.
===================引 用 river_l 文 章===================
請教一下 您在實做時是否有遇到以下問題 如果有或者您知道如何解決 可否請您告知 謝謝


GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-05-13 08:40:38 IP:203.75.xxx.xxx 未訂閱
純路過
請善加利用程式碼區塊編輯功能,避免系統保留字遺失,謝謝。

努力學習ing

請問 river_I 兄,你有include...
[code cpp]
先 #include
再 #include mysql.h
[/code]
上述這兩行嗎?
===================引 用 river_l 文 章===================
您好,

我將 mysql.h放在最後 include, 仍有以下問題, 可否再請教您如何解決此問題, 非常感謝您的幫忙

[code cpp]
#ifndef Unit1H
#define Unit1H
#include
#include
#include
#include
#include
#include
#include
#include
[/code]

...43...

編輯記錄
GrandRURU 重新編輯於 2008-05-13 08:44:18, 註解 無‧
river_l
一般會員


發表:4
回覆:9
積分:2
註冊:2007-04-26

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-05-13 10:43:38 IP:220.141.xxx.xxx 訂閱
您好,

謝謝您的回覆

[code cpp]
#include

#include mysql.h
[/code]

我都有做了 且 mysql.h是最後 include的
但仍有上述 my_socket 編譯錯誤 還請不吝指教 謝謝


===================引 用 GrandRURU 文 章===================
純路過
請善加利用程式碼區塊編輯功能,避免系統保留字遺失,謝謝。

努力學習ing

請問 river_I 兄,你有include...
[code cpp]
先 #include
再 #include mysql.h
[/code]
上述這兩行嗎?
===================引 用 river_l 文 章===================
您好,

我將 mysql.h放在最後 include, 仍有以下問題, 可否再請教您如何解決此問題, 非常感謝您的幫忙

[code cpp]
#ifndef Unit1H
#define Unit1H
#include
#include
#include
#include
#include
#include
#include
#include
[/code]

...43...
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-05-17 12:49:57 IP:140.134.xxx.xxx 未訂閱

[code cpp]
請在此區域輸入程式碼
#include
#include "C:\Program Files\MySQL\MySQL Server 5.1\include\mysql.h"
#include
#pragma hdrstop
#include "UForm1.h"

[/code]

我不是說得很清楚了嗎?
先 include windows.h 這個東西。再去 include mysql.h
而 include mysql.h 在第一次發表就有說要放在那邊了呀。
編輯記錄
暗黑破壞神 重新編輯於 2008-05-17 12:50:44, 註解 無‧
achillean
一般會員


發表:16
回覆:23
積分:7
註冊:2004-08-13

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-07-18 10:17:14 IP:218.210.xxx.xxx 訂閱
很感謝暗黑大分享這份入門操作
讓我完全不會MySQL,在短短一個禮拜可以簡單的操作C API
想補充是不是少了一行
[code cpp]
res = mysql_store_result(&mysql);
[/code]

除此之外我在使用CodeGear 2007的時候
常會發生因為連續呼叫mysql然後mysql的refence在第二次使用的時候會自動亂跑
導致程式讀取到非法區域中斷掉
請問有沒有人發生類似問題?

例如我沒辦法insert資料馬上呼叫更新Grid的函式
我必須把兩個動作分別寫在兩個按鍵中
不然程式就會當掉
附上一段程式碼

副程式
[code cpp]
int AddStaff(MYSQL &mysql,_Staff &theStaff)
{
char *cmd;
sprintf(cmd,"Insert into staff (Name,Username,Password) value('%s','%s','%s')",
&theStaff.stName,&theStaff.stUsername,&theStaff.stPassword);
mysql_query(&mysql,cmd);
return 1;
}
//---------------------------------------------------------------------------
int DelStaff(MYSQL &mysql,int ID)
{
char *cmd;
sprintf(cmd,"Delete From staff where ID='%d')",ID);
mysql_query(&mysql,cmd);
return 1;
}

[/code]

主程式
[code cpp]
//---------------------------------------------------------------------------
#include
#include "C:\Program Files\MySQL\MySQL Server 5.0\include\mysql.h"
#include
#pragma hdrstop

#include "Form_Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
StringGrid1->Cells[0][0] = "Staff ID";
StringGrid1->Cells[1][0] = "Name";
StringGrid1->Cells[2][0] = "Username";
StringGrid1->Cells[3][0] = "Password";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Btn_ConnectClick(TObject *Sender)
{
mysql_init(&mysql);
mysql_real_connect(&mysql,Edt_IP->Text.c_str(),Edt_ID->Text.c_str(),Edt_PW->Text.c_str(),"brck", 0, NULL, 0);
mysql_query(&mysql,"SET NAMES big5");
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Btn_AddStaffClick(TObject *Sender)
{
_Staff theStaff;
sprintf(theStaff.stName,Edt_Name->Text.c_str());
sprintf(theStaff.stUsername,Edt_Username->Text.c_str());
sprintf(theStaff.stPassword,Edt_Password->Text.c_str());
AddStaff(mysql,theStaff);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Btn_ST_RefreshClick(TObject *Sender)
{
MYSQL_RES *res;
MYSQL_ROW row;
mysql_query(&mysql, "SELECT * FROM staff");
res = mysql_store_result(&mysql);
int j = 0;
while ((row = mysql_fetch_row(res)) != NULL)
{
StringGrid1->RowCount = j 2;
StringGrid1->Cells[0][j 1] = row[0];
StringGrid1->Cells[1][j 1] = row[1];
StringGrid1->Cells[2][j 1] = row[2];
StringGrid1->Cells[3][j 1] = row[3];
j ;
}
mysql_free_result(res);
ShowMessage(mysql_error(&mysql));
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Btn_ST_DelClick(TObject *Sender)
{
DelStaff(mysql,StringGrid1->Cells[0][StringGrid1->Row].ToInt());
}
//---------------------------------------------------------------------------
[/code]

其中一種錯誤發生的方式
http://img182.imageshack.us/my.php?image=bugha2.png
編輯記錄
achillean 重新編輯於 2008-07-18 11:10:10, 註解 無‧
achillean 重新編輯於 2008-07-18 11:11:37, 註解 無‧
achillean 重新編輯於 2008-07-18 11:12:08, 註解 無‧
achillean
一般會員


發表:16
回覆:23
積分:7
註冊:2004-08-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-07-18 14:49:20 IP:218.210.xxx.xxx 訂閱
問題以找到
char *cmd沒有配置空間
所以間接影響到mysql的位址
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#10 引用回覆 回覆 發表時間:2008-07-18 18:31:51 IP:60.249.xxx.xxx 未訂閱
嗯。好像貼掉了。:Q

其實。用這種方法。簡單,而且可以趴過 BDE,只是要自己維護 GUI 元件跟 data 的關係。
可是省掉程式出去了還要包裝的麻煩。

===================引 用 achillean 文 章===================

[code cpp]
res = mysql_store_result(&mysql);
[/code]
kostin
一般會員


發表:18
回覆:43
積分:22
註冊:2010-03-11

發送簡訊給我
#11 引用回覆 回覆 發表時間:2010-04-22 09:21:00 IP:122.127.xxx.xxx 訂閱
小弟是菜鳥
請問大大 您說的這招要怎麼使用阿
小弟看不懂
小弟目前用的平台是 bcb6 mysql 4.1
//********************************************************************************************
我們開個 dos session 來做些事。
implib t.lib libmysql.dll
這一招可以把 libmysql.dll 變成我們能用的 lib.
//*******************************************************************************************
------
工程師的世界太深奧了 ~ 總是有不斷的驚奇發生
在解決問題的當下 , 才能確認我的存在
在得到幫助的當下 , 才能發現我不孤單
rick060
高階會員


發表:2
回覆:112
積分:217
註冊:2009-11-17

發送簡訊給我
#12 引用回覆 回覆 發表時間:2011-06-29 16:37:49 IP:60.250.xxx.xxx 未訂閱
這是最近在玩 mysql 用 delphi 做出來的wrapper , delphi 不像 C 可以 static link ,所以 delphi 用起來仍然需要 libmysql.dll
功能很陽春..倒是可以試一試。

基本用法:

[code delphi]

var
pMySQL : MySQLInterface;
begin
try
pMySQL := MySQLInterface.Create;

pMySQL.Host := 'hostIP';//設定連線
pMySQL.User := 'root';
pMySQL.Password := 'root';
pMySQL.DefaultDataBase := 'db';
pMySQL.Port := 3306;
pMySQL.Connect;//連線

pMySQL.SQL := 'select * from table'
pMySQL.Open;

while pMySQL.HasRow do
begin
pMySQL.Fields(0); //column0 的資料
pMySQL.Fields(1); //column1 的資料
pMySQL.Fields(2); //column2 的資料
end;
except on E : Exception do
func_WriteLog( Format('處理錯誤:[%s]',[E.Message]) ,True )
end;
if Assigned(pMySQL) then
pMySQL.Free;
end;

[/code]

至於 prepare 的用法..


[code delphi]
var
pMySQL : MySQLInterface;
pBind : MYSQL_BIND;
dataLen : Cardinal;
inputArray : array[0..127] of Ansichar;
outputArray : array[0..127] of Ansichar;
begin
try
pMySQL := MySQLInterface.Create;
func_InitSQL(pMySQL);

pMySQL.Prepare('select mail_id from quarantine limit 1');
pMySQL.Execute;
ZeroMemory(@pBind,sizeof(pBind));
pBind.buffer := @outputArray;
pBind.buffer_length := sizeof(outputArray);
pBind.length := @dataLen;
pMySQL.BindOutput(@pBind);

while pMySQL.Fetch do
begin
pMySQL.FetchColumn(@pBind,0,0); //column 0 的資料
ShowMessage(outputArray);
end;

pMySQL.Prepare('select mail_id from quarantine where mail_id = ?');

inputArray := 'NjVlXi8jLOXO';
dataLen := StrLen(inputArray);
ZeroMemory(@pBind,sizeof(pBind));
pBind.buffer := @inputArray;
pBind.length := @dataLen;
pBind.buffer_type := Integer(MYSQL_TYPE_STRING);

pMySQL.BindInput(@pBind);
ZeroMemory(@pBind,sizeof(pBind));
pBind.buffer := @outputArray;
pBind.buffer_length := sizeof(outputArray);
pBind.length := @dataLen;
pMySQL.BindOutput(@pBind);

while pMySQL.Fetch do
begin
pMySQL.FetchColumn(@pBind,0,0);
ShowMessage(outputArray);
end;
finally
pMySQL.Free;
end;
end;
[/code]




[code delphi]

unit mysql_wrapper;

interface

uses
Windows,SysUtils,Dialogs,Variants;

const
/// status return codes
MYSQL_NO_DATA = 100;
MYSQL_DATA_TRUNCATED = 101;

type
MYSQL = Pointer;
MYSQL_RES = Pointer;
MYSQL_STMT = Pointer;

type
MYSQL_TYPE = ( MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
MYSQL_TYPE_BIT,
MYSQL_TYPE_NEWDECIMAL=246,
MYSQL_TYPE_ENUM=247,
MYSQL_TYPE_SET=248,
MYSQL_TYPE_TINY_BLOB=249,
MYSQL_TYPE_MEDIUM_BLOB=250,
MYSQL_TYPE_LONG_BLOB=251,
MYSQL_TYPE_BLOB=252,
MYSQL_TYPE_VAR_STRING=253,
MYSQL_TYPE_STRING=254,
MYSQL_TYPE_GEOMETRY=255,
MAX_NO_FIELD_TYPES);

type
MYSQL_BIND = packed Record
length : PCardinal;
is_null : PAnsiChar;
buffer : Pointer;
error : PAnsiChar;
row_ptr : PByte;
store_param_func : Pointer;
fetch_result : Pointer;
skip_result : Pointer;
buffer_length : Cardinal;
offset : Cardinal;
length_value : Cardinal;
param_number : Cardinal;
pack_length : Cardinal;
buffer_type : Integer;
error_value : AnsiChar;
is_unsinged : AnsiChar;
long_data_used : AnsiChar;
is_null_value : AnsiChar;
extension : Pointer;
end;

type
MySQLInterface = Class
constructor Create;
destructor Destroy; override;

private
FLibraryHandle : THandle; //dll Handle
FMySQLHandle : MYSQL;
FMySQLRes : MYSQL_RES;
FMySQLStmt : MYSQL_STMT;
FfieldHandle : Pointer;
FSQL : AnsiString;
FHost : AnsiString;
FUser : AnsiString;
FPassword : AnsiString;
FDataBase : AnsiString;
FPort : Cardinal;
FAutoCommit : Boolean;

mysql_initPtr : function(pmysql:MYSQL):MYSQL;stdcall;
mysql_closePtr : procedure(pmysql:MYSQL);stdcall;
mysql_real_connectPtr : function(pmysql:MYSQL;host:PAnsiChar;user:PAnsiChar;passwd:PAnsiChar;db:PAnsiChar;port :Cardinal;unix_socket:PAnsiChar;clientflag:Cardinal):MYSQL;stdcall;
mysql_errorPtr : function(pmysql:MYSQL):PAnsiChar;stdcall;
mysql_queryPtr : function(pmysql:MYSQL;stmt_str:PAnsiChar):Integer;stdcall;
mysql_use_resultPtr : function(pmysql:MYSQL):MYSQL_RES;stdcall;
mysql_fetch_rowPtr : function(pres:MYSQL_RES):PPAnsiChar;stdcall;
mysql_free_resultPtr : procedure(pres:MYSQL_RES);stdcall;
mysql_num_fieldsPtr : function(pres:MYSQL_RES):Cardinal;stdcall;
mysql_num_rowsPtr : function(pres:MYSQL_RES):UINT64;stdcall;
mysql_store_resultPtr : function(pmysql:MYSQL):MYSQL_RES;stdcall;
mysql_errnoPtr : function(pmysql:MYSQL):Cardinal;stdcall;
mysql_stmt_initPtr : function(pmysql:MYSQL):MYSQL_STMT;stdcall;
mysql_affected_rowsPtr : function(pmysql:MYSQL):UINT64;stdcall;
mysql_autocommitPtr : function(pmysql:MYSQL;my_bool:WORD):Byte;stdcall;
mysql_commitPtr : function(pmysql:MYSQL):Byte;stdcall;
mysql_rollbackPtr : function(pmysql:MYSQL):Byte;stdcall;
mysql_stmt_preparePtr : function(pstmt:MYSQL_STMT;stmt_str:PAnsiChar;length:Cardinal):Integer;stdcall;
mysql_stmt_bind_paramPtr : function(pstmt:MYSQL_STMT;bind:Pointer):Byte;stdcall;
mysql_stmt_bind_resultPtr : function(pstmt:MYSQL_STMT;bind:Pointer):Byte;stdcall;
mysql_stmt_executePtr : function(pstmt:MYSQL_STMT):Integer;stdcall;
mysql_stmt_fetchPtr : function(pstmt:MYSQL_STMT):Integer;stdcall;
mysql_stmt_closePtr : function(pstmt:MYSQL_STMT):Byte;stdcall;
mysql_stmt_affected_rowsPtr : function(pstmt:MYSQL_STMT):UINT64;stdcall;
mysql_stmt_fetch_columnPtr : function(pstmt:MYSQL_STMT;bind:Pointer;column:Cardinal;offset:Cardinal):Integer;stdcall;

procedure SetSQLText(szSQL:AnsiString);
procedure SetAutoCommit(IsAutoCommit:Boolean);
function dumpError:AnsiString;
function GetErrno : Cardinal;
public
procedure Open;
procedure Exec;
procedure Connect;
procedure Commit;
procedure RollBack;
procedure Execute;
procedure Prepare(szSQL:AnsiString);
procedure BindInput(bind:Pointer);
procedure BindOutput(bind:Pointer);
function Fields(nField:Integer):Variant;
function AffectedRows:UINT64;
function StmtAffectedRows:UINT64;
function HasRow:Boolean;
function Fetch:Boolean;
function FetchColumn(pBind:Pointer;nColumn:Cardinal;nOffset:Cardinal):Variant;

property SQL : AnsiString read FSQL write SetSQLText;
property errno : Cardinal read GetErrno;
property Host : AnsiString read FHost write FHost;
property User : AnsiString read FUser write FUser;
property Password : AnsiString read FPassword write FPassword;
property DefaultDataBase : AnsiString read FDataBase write FDataBase;
property Port : Cardinal read FPort write FPort;
property AutoCommit : Boolean read FAutoCommit write SetAutoCommit;
end;

implementation

{ MySQLInterface }

constructor MySQLInterface.Create;
begin
FLibraryHandle := LoadLibrary( 'libmysql.dll' );
if THandle(FLibraryHandle) = 0 then
raise Exception.Create('LoadLibrary() libmysql.dll Error');

@mysql_initPtr := GetProcAddress(FLibraryHandle, 'mysql_init');
if THandle(@mysql_initPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_init Error');

@mysql_closePtr := GetProcAddress(FLibraryHandle, 'mysql_close');
if THandle(@mysql_closePtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_close Error');

@mysql_real_connectPtr := GetProcAddress(FLibraryHandle, 'mysql_real_connect');
if THandle(@mysql_real_connectPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_real_connect Error');

@mysql_errorPtr := GetProcAddress(FLibraryHandle, 'mysql_error');
if THandle(@mysql_errorPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_error Error');

@mysql_queryPtr := GetProcAddress(FLibraryHandle, 'mysql_query');
if THandle(@mysql_queryPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_query Error');

@mysql_use_resultPtr := GetProcAddress(FLibraryHandle, 'mysql_use_result');
if THandle(@mysql_use_resultPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_use_result Error');

@mysql_fetch_rowPtr := GetProcAddress(FLibraryHandle, 'mysql_fetch_row');
if THandle(@mysql_fetch_rowPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_fetch_row Error');

@mysql_free_resultPtr := GetProcAddress(FLibraryHandle, 'mysql_free_result');
if THandle(@mysql_free_resultPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_free_result Error');

@mysql_num_fieldsPtr := GetProcAddress(FLibraryHandle, 'mysql_num_fields');
if THandle(@mysql_num_fieldsPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_num_fields Error');

@mysql_num_rowsPtr := GetProcAddress(FLibraryHandle, 'mysql_num_rows');
if THandle(@mysql_num_rowsPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_num_rows Error');

@mysql_store_resultPtr := GetProcAddress(FLibraryHandle, 'mysql_num_rows');
if THandle(@mysql_store_resultPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_num_rows Error');

@mysql_errnoPtr := GetProcAddress(FLibraryHandle, 'mysql_errno');
if THandle(@mysql_errnoPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_errno Error');

@mysql_stmt_initPtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_init');
if THandle(@mysql_stmt_initPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_init Error');

@mysql_affected_rowsPtr := GetProcAddress(FLibraryHandle, 'mysql_affected_rows');
if THandle(@mysql_affected_rowsPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_affected_rows Error');

@mysql_autocommitPtr := GetProcAddress(FLibraryHandle, 'mysql_autocommit');
if THandle(@mysql_autocommitPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_autocommit Error');

@mysql_commitPtr := GetProcAddress(FLibraryHandle, 'mysql_commit');
if THandle(@mysql_commitPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_commit Error');

@mysql_rollbackPtr := GetProcAddress(FLibraryHandle, 'mysql_rollback');
if THandle(@mysql_rollbackPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_rollback Error');

@mysql_stmt_preparePtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_prepare');
if THandle(@mysql_stmt_preparePtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_prepare Error');

@mysql_stmt_bind_paramPtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_bind_param');
if THandle(@mysql_stmt_bind_paramPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_bind_param Error');

@mysql_stmt_executePtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_execute');
if THandle(@mysql_stmt_executePtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_execute Error');

@mysql_stmt_fetchPtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_fetch');
if THandle(@mysql_stmt_fetchPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_fetch Error');

@mysql_stmt_closePtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_close');
if THandle(@mysql_stmt_closePtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_close Error');

@mysql_stmt_affected_rowsPtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_affected_rows');
if THandle(@mysql_stmt_affected_rowsPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_affected_rows Error');

@mysql_stmt_bind_resultPtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_bind_result');
if THandle(@mysql_stmt_bind_resultPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_bind_result Error');

@mysql_stmt_fetch_columnPtr := GetProcAddress(FLibraryHandle, 'mysql_stmt_fetch_column');
if THandle(@mysql_stmt_fetch_columnPtr) = 0 then
raise Exception.Create('GetProcAddress() libmysql.dll -> mysql_stmt_fetch_column Error');

FMySQLHandle := mysql_initPtr(nil);

if FMySQLHandle = nil then
raise Exception.Create('mysql_init() Error');
end;

destructor MySQLInterface.Destroy;
begin
mysql_closePtr(FMySQLHandle);
FreeLibrary( FLibraryHandle );
inherited;
end;

function MySQLInterface.AffectedRows: UINT64;
begin
Result := mysql_affected_rowsPtr(FMySQLHandle);
end;

procedure MySQLInterface.Commit;
begin
if mysql_commitPtr(FMySQLHandle) <> 0 then
raise Exception.Create(dumpError);
end;

procedure MySQLInterface.Connect;
var
pRet : MYSQL;
szErrMsg : AnsiString;
begin
pRet := mysql_real_connectPtr(FMySQLHandle,PAnsiChar(FHost)
,PAnsiChar(FUser),PAnsiChar(FPassword),PAnsiChar(FDatabase)
,FPort,'',0);
if pRet <> FMySQLHandle then
raise Exception.Create(dumpError);
end;

function MySQLInterface.Fetch: Boolean;
var
nRes : Integer;
begin
Result := False;

nRes := mysql_stmt_fetchPtr(FMySQLStmt);

if nRes in [1,MYSQL_NO_DATA,MYSQL_DATA_TRUNCATED] then
mysql_stmt_closePtr(FMySQLStmt);

if nRes = 1 then
raise Exception.Create(dumperror);

if nRes in [0,MYSQL_DATA_TRUNCATED] then
Result := True;
end;

function MySQLInterface.FetchColumn(pBind:Pointer;nColumn:Cardinal;nOffset:Cardinal): Variant;
var
nRes : Integer;
begin
nRes := mysql_stmt_fetch_columnPtr(FMysqlStmt,pBind,nColumn,nOffset);
if nRes <> 0 then
raise Exception.Create(Format('mysql_stmt_fetch_column() error:[%d]',[nRes]));
end;

function MySQLInterface.Fields(nField: Integer): Variant;
var
ptrOffset : Cardinal;
nCount : Integer;
begin
nCount := mysql_num_fieldsPtr(FMySQLRes);
if nField >= nCount then
raise Exception.Create('field index out of range');

Result := AnsiString(PAnsiChar(PInteger(Cardinal(FfieldHandle) (sizeof(Pointer) * nField))^));
end;

procedure MySQLInterface.SetAutoCommit(IsAutoCommit: Boolean);
begin
if mysql_autocommitPtr(FMySQLHandle,Word(IsAutoCommit)) <> 0 then
raise Exception.Create(dumpError);
end;

procedure MySQLInterface.SetSQLText(szSQL:AnsiString);
begin
while HasRow do;
Self.FSQL := szSQL;
end;

function MySQLInterface.StmtAffectedRows: UINT64;
begin
Result := mysql_stmt_affected_rowsPtr(FMySQLStmt);
end;

procedure MySQLInterface.Open;
begin
if mysql_queryPtr(FMySQLHandle,PAnsiChar(FSQL)) <> 0 then
raise Exception.Create(dumpError);

FMySQLRes := mysql_use_resultPtr(FMySQLHandle);
if FMySQLRes = nil then
raise Exception.Create(dumpError);
end;

function MySQLInterface.HasRow: Boolean;
begin
Result := False;

if FMySQLRes = nil then
Exit;

FfieldHandle := mysql_fetch_rowPtr(FMySQLRes);
if FfieldHandle <> nil then
Result := True
else
begin
mysql_free_resultPtr(FMySQLRes);
FMySQLRes := nil;
end;
end;

procedure MySQLInterface.BindInput(bind:Pointer);
var
nRes : Integer;
begin
nRes := mysql_stmt_bind_paramPtr(FMySQLStmt,bind);
if nRes <> 0 then
raise Exception.Create(Format('mysql_stmt_bind_param() error:[%d]',[nRes]));

nRes := mysql_stmt_executePtr(FMySQLStmt);
if nRes <> 0 then
raise Exception.Create(Format('mysql_stmt_execute() error:[%d]',[nRes]));
end;

procedure MySQLInterface.BindOutput(bind: Pointer);
var
nRes : Integer;
begin
nRes := mysql_stmt_bind_resultPtr(FMySQLStmt,bind);
if nRes <> 0 then
raise Exception.Create(Format('mysql_stmt_bind_result() error:[%d]',[nRes]));
end;

function MySQLInterface.dumpError: AnsiString;
begin
Result := Format('mysql Process error:[%s] Errno:[%d]',[mysql_errorPtr(FMySQLHandle),mysql_errnoPtr(FMySQLHandle)]);
end;

function MySQLInterface.GetErrno: Cardinal;
begin
Result := mysql_errnoPtr(FMySQLHandle);
end;

procedure MySQLInterface.Exec;
begin
if mysql_queryPtr(FMySQLHandle,PAnsiChar(FSQL)) <> 0 then
raise Exception.Create(dumpError);
end;

procedure MySQLInterface.Execute;
var
nRes : Integer;
begin
nRes := mysql_stmt_executePtr(FMySQLStmt);
if nRes <> 0 then
raise Exception.Create(Format('mysql_stmt_execute() error:[%d]',[nRes]));
end;

procedure MySQLInterface.Prepare(szSQL: AnsiString);
begin
FSQL := szSQL;

FMySQLStmt := mysql_stmt_initPtr(FMySQLHandle);
if FMySQLStmt = nil then
raise Exception.Create(dumpError);
if mysql_stmt_preparePtr(FMySQLStmt,PAnsiChar(FSQL),Length(FSQL)) <> 0 then
raise Exception.Create(dumpError);
end;

procedure MySQLInterface.RollBack;
begin
if mysql_rollbackPtr(FMySQLHandle) <> 0 then
raise Exception.Create(dumpError);
end;

end.
[/code]
系統時間:2024-11-21 16:38:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!