以下对一些常用函数的用法按调用顺序作了一个简单的说明。
1.连接mysql数据库
连接用到两个函数:mysql_init()和mysql_real_connect(),定义如下:
MYSQL *mysql_init(MYSQL *mysql);
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned int client_flag);
mysql_init初始化mysql句柄,供mysql_real_connect使用,如果mysql是一个NULL指针,函数分配、初始化并且返回一个新对象。否则对象被初始化并且返回对象的地址。mysql_real_connect 根据提供的mysql数据库服务器的地址,mysql用户名,密码,数据库名称,端口,等建立同数据库的连接,unix_socket一般为NULL,client_flag一般为0,如有特殊要求参见mysql参考手册。如果连接成功,一个 MYSQL*连接句柄。如果连接失败,NULL。
2.查询
查询有两个函数mysql_query()和mysql_real_connect()
int mysql_query(MYSQL *mysql, const char *query);
int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length);
mysql为mysql_real_connect返回的句柄,query为sql语句,mysql_query的query中不能包含含有’\0’的二进制数据,而mysql_real_query可以,然而,在插入blob字段时,你可以用mysql_escape_string先进行转换。若查询成功,两个函数都返回零。
3.存储结果
连接库定义了一个结果集的结构:MYSQL_RES,来存储返回的结果;根据不同的查询,返回的结果不同,以下是几种常见的结果;
数据记录:Select语句返回的满足条件的记录;
表结构:mysql_list_fields或SHOW COLUMNS FROM tbl_name [LIKE wild]语句返回
数据表:mysql_list_tables或SHOW tables [LIKE wild]返回
数据库:mysql_list_dbs或SHOW databases [LIKE wild]返回
用mysql_query或mysql_real_query查询时,要用mysql_store_result()或mysql_use_result()保存结果,他们都返回一个MYSQL_RES结构指针。mysql_list_fields,mysql_list_tables,mysql_list_dbs,直接返回MYSQL_RES结构指针,存储查询结果之后,就可以调用函数来取出需要的数据。4. 取数据
以下是一些常用的取数据的函数:
a. MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result);获取结果集中的一个字段信息,可连续调用直到返回NULL。
b. unsigned int mysql_num_fields(MYSQL *mysql);返回结果集中的字段数。
c. MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);获取结果集中的一行记录,可连续调用直到返回NULL。返回值是一个字符串数组的指针。
d. unsigned long *mysql_fetch_lengths(MYSQL_RES *result);返回结果集中当前行的每个字段的长度,返回值是一个整数数组的指针。必须在mysql_fetch_row之后调用,以和mysql_fetch_row检索的记录对应。可连续调用直到返回NULL。
以上只是对一些常用的连接库函数按调用顺序作了一个简单的说明,详细资料参见mysql的使用手册。
直接用mysql连接库在构建用户界面方面有一些麻烦,Delphi的TClientDataSet 组件可以创建内存表,在不需要很全面的功能的时候,用它来作为用户和mysql数据库之间的桥梁,非常方便。
以下是一个创建表的函数,类型转换不全,只转换了几种我需要的。
function CreateResultTable(szsql:string;pmysqlstruct:PMYSQL;
var cds:TClientDataSet):integer;
type
arrinteger=array[00..$ff] of integer;
PArrinteger=^arrinteger;
var
row :PMYSQL_ROW;
num_fields:integer;
i:integer;
presult:PMYSQL_RES;
pmyfield:PMYSQL_FIELD;
plengths:PArrinteger;
strm:TMemoryStream;
begin
result:=0;
if mysql_query(pmysqlstruct,PChar(szsql))<>0 then begin
Result :=1;
Exit;
end;
presult:=mysql_store_result(pmysqlstruct);
if presult=nil then begin
Result:=2;
Exit;
end;
cds.Close;
cds.FieldDefs.Clear;
pmyfield:=mysql_fetch_field(presult);
while pmyfield<>nil do begin
with cds.FieldDefs.AddFieldDef do begin
Name:=pmyfield.name;
case pmyfield._type of
FIELD_TYPE_LONG,FIELD_TYPE_LONGLONG: DataType:=ftLargeint;
FIELD_TYPE_DATETIME: DataType:=ftDateTime;
FIELD_TYPE_VAR_STRING,FIELD_TYPE_STRING:
begin
DataType:=ftString;
size:=pmyfield.length;
end;
FIELD_TYPE_BLOB,FIELD_TYPE_TINY_BLOB,FIELD_TYPE_MEDIUM_BLOB,FIELD_TYPE_LONG_BLOB: DataType:=ftBlob;
else DataType:=ftUnknown;
end;
end;
pmyfield:=mysql_fetch_field(presult);
end;
try
cds.CreateDataSet;
except
mysql_free_result(presult);
Result:=3;
Exit;
end;
strm:=TMemoryStream.Create;
{strList是字段的显示对照字典,根据需要创建一个TStringList,作如下初始化:strList.Text:='UserID=序列号'+#13+'UserName=用户名'+#13 ...;}
{ for i:=0 to cds.FieldCount-1 do
begin
if strList.Values[cds.FieldDefs[i].name]<>'' then
cds.Fields[i].DisplayLabel:=strList.Values[cds.FieldDefs[i].name];
end;}
num_fields:= mysql_num_fields(presult);
row:=mysql_fetch_row(presult);
if row=nil then result:=4;
while (row<>nil) do
begin
plengths:=PArrinteger(mysql_fetch_lengths(presult));
cds.Insert;
for i:=0 to num_fields-1 do
begin
with cds.Fields[i] do begin
if IsBlob then begin
strm.Clear;
strm.Write(row[i]^,plengths[i]);
(cds.Fields[i] as TBlobField).LoadFromStream(strm);
end
else cds.Fields[i].AsString:=row[i];
end;
end;
cds.Post;
row:=mysql_fetch_row(presult);
end;
strm.Free;
mysql_free_result(presult);
end;