在labwindows下使用mysql C API 访问数据库的流程如下:
1.创建MYSQL对象句柄。
函数原型:MYSQL *mysql_init(MYSQL *mysql)
该函数形参和返回值均为MYSQL指针。MySQL结构表示一个数据库连接句柄。几乎后面所有的函数均使用此句柄与musql通信。
如果形参是NULL指针,该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。
mysql_init()分配的对象,必须要调用mysql_close()来关闭连接时,将释放该对象。
返回值:初始化的MYSQL*句柄。如果没有足够的内存分配新对象,则返回NULL。
另外先介绍一下另外两个错误显示函数,在编程过程中,错误显示函数非常重要,通过此函数,可以非常清晰的了解错误到底在哪里。
(1)unsigned int mysql_errno(MYSQL *mysql);
形参为MYSQL句柄,返回值为最近调用的API函数的错误代码,该函数调用可能成功也可能失败。“0”返回值表示未出现错误。在MySQL errmsg.h头文件中,列出了客户端错误消息编号。
(2)const char *mysql_error(MYSQL *mysql)
形参为MYSQL句柄,返回包含错误消息的、由Null终结的字符串。
一般用这两个函数构建一个错误显示函数,用来显示错误。代码如下:
void printfError(MYSQL *mysqlHandle,const char *title)
{
fprintf(stderr,"%s:\nError Code:%u(%s)\n",title,mysql_errno(mysqlHandle),
mysql_error(mysqlHandle));
}
此函数在命令行中显示错误代码。也可以弹出窗的形式显示。
2.连接数据库
函数原型: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 long client_flag);
形参意义:
MYSQL *mysql为对象句柄,是mysql_init返回值;
host 服务器Ip地址,如果为本地服务器,设置为Null或者localhost;
char *user, const char *passwd, const char *db 分别表示用户名,密码,数据库名称;
unsigned int port 表示端口号,本地设置为0。
const char *unix_socket 表示套接字,本地设置为0;
unsigned long client_flag 表示客户端访问服务器的模式,通常设置为0,表示一般模式.主要模式有以下(来自官网):
-
-
CAN_HANDLE_EXPIRED_PASSWORDS
: The client can handle expired passwords. -
CLIENT_COMPRESS
: Use compression in the client/server protocol. -
CLIENT_FOUND_ROWS
: Return the number of found (matched) rows, not the number of changed rows. -
CLIENT_IGNORE_SIGPIPE
: Prevents the client library from installing aSIGPIPE
signal handler. This can be used to avoid conflicts with a handler that the application has already installed. -
CLIENT_IGNORE_SPACE
: Permit spaces after function names. Makes all functions names reserved words. -
CLIENT_INTERACTIVE
: Permitinteractive_timeout
seconds of inactivity (rather thanwait_timeout
seconds) before closing the connection. The client's sessionwait_timeout
variable is set to the value of the sessioninteractive_timeout
variable. -
CLIENT_LOCAL_FILES
: EnableLOAD DATA LOCAL
handling. -
CLIENT_MULTI_RESULTS
: Tell the server that the client can handle multiple result sets from multiple-statement executions or stored procedures. This flag is automatically enabled ifCLIENT_MULTI_STATEMENTS
is enabled. See the note following this table for more information about this flag. -
CLIENT_MULTI_STATEMENTS
: Tell the server that the client may send multiple statements in a single string (separated by;
characters). If this flag is not set, multiple-statement execution is disabled. See the note following this table for more information about this flag. -
CLIENT_NO_SCHEMA
Do not permitdb_name.tbl_name.col_name
syntax. This is for ODBC. It causes the parser to generate an error if you use that syntax, which is useful for trapping bugs in some ODBC programs. -
CLIENT_ODBC
: Unused. -
CLIENT_SSL
: Use SSL (encrypted protocol). Do not set this option within an application program; it is set internally in the client library. Instead, usemysql_options()
ormysql_ssl_set()
before callingmysql_real_connect()
. -
CLIENT_REMEMBER_OPTIONS
Remember options specified by calls tomysql_options()
. Without this option, ifmysql_real_connect()
fails, you must repeat themysql_options()
calls before trying to connect again. With this option, themysql_options()
calls need not be repeated.
-
到此,mysql与服务器建立连接。
#include <stdio.h>
#include <ansi_c.h>
#define MYSQL_ABI_CHECK
#include "mysql.h"
static char *Host=NULL;
static char *User="root";
static char *Passwd="100on";
static unsigned Port=0;
static char *SocketName=NULL;
static char *DatabaseName="lianxi";
static unsigned clientflag=0;
static MYSQL *mysqlHandle;
void ShowData(MYSQL *mysqlHandle) ;
void printfError(MYSQL *mysqlHandle,const char *title)
{
fprintf(stderr,"%s:\nError Code:%u(%s)\n",title,mysql_errno(mysqlHandle),
mysql_error(mysqlHandle));
}
int main(int argc,char *argv[])
{
if((mysqlHandle=mysql_init(mysqlHandle))==NULL)
{
printfError(mysqlHandle,"ERROR");
exit(1);
}
else
{
fprintf(stderr,"mysql 初始化成功!\n");
}
if(mysql_real_connect(mysqlHandle,Host,User,Passwd,DatabaseName,Port,
SocketName,clientflag)==NULL)
{
printfError(mysqlHandle,"ERROR");
mysql_close(mysqlHandle);
getchar();
exit(1);
}
fprintf(stderr, "mysql 连接成功!\n");
mysql_close(mysqlHandle);
getchar();
return 0;
}
3、查看数据库
查看数据库需要几个函数配合使用,基本流程如下:
(1)int mysql_real_query(MYSQL *mysql, const char *stmt_str, unsigned long length);
此函数用来执行stmt_str(字符串长度为length
)所指向的SQL语句。通常,该字符串必须由单个SQL语句组成,不带终止分号(;)或\g。
此函数一般只能用来执行单条语句,如果需要执行多条语句,则在连接数据库是需要选择执行多条语句的模式才行。
返回值为0,则代表执行成功。
所以一般查询的时候首先用此函数来执行查询语句。
(2)通过查询语句产生的结果在服务器上,需要使用mysql_store_result或mysql_use_result函数返回查询的结果集。
两个函数的原型分别为:
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
mysql_store_result函数把从MYSQL服务器查询的所有数据都存储到客户端,然后读取;
mysql_use_result函数初始化检索,以便于后面一行一行的读取结果集,而他本身并没有从服务器读取任何数据,这种方式快切并且占内存小,但是它会独占服务器,而且必须重复执行mySql_fetch_row直到返回NULL,否则未读取的行会作为下一次的查询结果返回。
(3)调用mysql_fetch_row函数读取结果集数据。
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
前面查询的语句可能不止1行,但是此函数每次只能读取一行数据,所以需要此很熟循环执行,当结果集到结尾时,此函数返回NULL。
参数result就是mysql_store_result或mysql_use_result的返回值。返回值MYSQL_ROW为字符串数组,第n个数组代表第n个字段的值。如果到结果集结尾或者发生错误,则为空。
(4)调用完结果集后,需要释放结果集。
void STDCALL mysql_free_result(MYSQL_RES *result);
4.向数据库插入数据
(1)int mysql_real_query(MYSQL *mysql, const char *stmt_str, unsigned long length);
此函数用来执行stmt_str(字符串长度为length
)所指向的SQL语句。通常,该字符串必须由单个SQL语句组成,不带终止分号(;)或\g。
(2)my_ulonglong mysql_affected_rows(MYSQL *mysql)
;
此函数用在mysql_real_query函数之后,返回变化的总行数。如果mysql_real_query函数中的mysql语句是insert、update或者delete,则返回值为实际变化的行数(insert:插入行数,update:更改行数,delete为删除函数)。对于select语句,其作用和mysql_num_rows一样。
void insertData(MYSQL * mysqlHandle)
{
char InsertStatement[200]="insert into orders values(NULL,1,10)";
if(mysql_real_query(mysqlHandle,InsertStatement,strlen(InsertStatement)))
{
printfError(mysqlHandle,"ERROR");
}
else
{
printf("插入成功,受影响行数为:%lu\n",(unsigned)
mysql_affected_rows(mysqlHandle));
}
}
5.删除数据
void DeleteData( MYSQL *mysqlHandle)
{
char DeleteStatement[200]="delete from orders where goods_number=10";
if(mysql_real_query(mysqlHandle,DeleteStatement,strlen(DeleteStatement)))
{
printfError(mysqlHandle,"ERROR");
}
else
{
printf(删除成,受影响行数:%lu\n",(unsigned)
mysql_affected_rows(mysqlHandle));
}
}
6.更新数据
void UpdateData(MYSQL *mysqlHandle)
{
char UpdateStatement[200]="Update orders set goods_number=8 where goods_ID=1";
if(mysql_real_query(mysqlHandle,UpdateStatement,strlen(UpdateStatement)))
{
printfError(mysqlHandle,"ERROR");
}
else
{
printf("更新数据库成功:%lu\n",(unsigned)
mysql_affected_rows(mysqlHandle));
}
}