Chinaunix首页 | 论坛 | 博客
  • 博客访问: 198858
  • 博文数量: 69
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 720
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-03 11:35
文章分类

全部博文(69)

文章存档

2011年(13)

2010年(46)

2009年(10)

我的朋友

分类: Mysql/postgreSQL

2010-01-06 16:23:39

MySql 100106Connector/C II

@ http://zcatt.cublog.cn

 

1.Prepared statement

Prepared statement(翻成 预编 ?)是一种不同于直接执行(查询)的方式。直接执行方式中,每次查询都会解析一次查询语句,再执行。而预编模式则可以将解析的结果保存,再执行。这样对于同一查询反复执行的情景,只需执行一次解析,后面反复执行这个解析的结果就成了,只需每次执行时给定语句中的参数。从而实现效率的提高。

注意的是,并不是所有环境下预编都会比直接执行的效率高。

支持预编模式的语句大致有:CALL, CREATE TABLE, DELETE, DO, INSERT, REPLACE, SELECT, SET, UPDATE

 

 

2.框架

基本步骤:

a) mysql_stmt_init(), 初始化

b) mysql_stmt_prepare, 预编译语句

loop begin

c) mysql_stmt_bind_param(),给定每次查询的参数

d) mysql_stmt_execute(), 执行

e) mysql_stmt_bind_result() 绑定结果输出缓冲

f) mysql_stmt_store_result(), 获取全部结果

loop begin

g)mysql_stmt_fetch(),取一行结果

loop end

loop end

h) mysql_stmt_close(),释放

 

一个查询对应一个prepared statement,调用mysql_stmt_init后会得到一个handle,使用完后应该closestmt handle 数据库连接(connection)的关系是多对一的关系。

 

3.主要数据结构

1) MYSQL_STMT

stmt handle的机构,代表一个prepared语句。mysql_stmt_init()生成,mysql_stmt_close()注销。

 

2MYSQL_BIND

用于给定输入的语句参数,和输出的结果。使用前应当用0初始化。语句中参数使用'?'占位。

其中几个重要的域

field

inputbind param

output (bind result)

enum enum_field_types buffer_type

值的类型

期望接收的值类型

void *buffer

参数的内容

保存结果的buffer

unsigned long buffer_length

*buffer的长度

*buffer能容纳的最大长度

unsigned long *length

实际长度。数字类型的值,此域忽略。

实际长度。数字类型的值,此域忽略。

my_bool *is_null

是否这个域传入NULL

域值是否NULL

my_bool is_unsigned

是否unsigned

是否unsigned

my_bool *error

 

对于truncate有特别的用途。

 

3MYSQL_TIME

用于表示DATE,TIME,DATETIMETIMESTAMP

4. 主要函数

 

id

func

Description

1

mysql_stmt_init()

分配stmt handle结构内存,初始化

2

mysql_stmt_close()

释放stmt handle

3

mysql_stmt_prepare()

预编查询/语句

4

mysql_stmt_bind_param()

绑定入口参数

5

mysql_stmt_bind_result()

绑定出口参数

6

mysql_stmt_execute()

执行

7

mysql_stmt_store_result()

取回所有结果

8

mysql_stmt_fetch()

取一行结果。

 

5.例子

预备条件:

server上的账户 root:passwd@localhost:3306, 数据库是world, 其中的表city结构如下

 

mysql> desc city;

+-------------+----------+------+-----+---------+----------------+

| Field       | Type     | Null | Key | Default | Extra          |

+-------------+----------+------+-----+---------+----------------+

| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |

| Name        | char(35) | NO   |     |         |                |

| CountryCode | char(3)  | NO   |     |         |                |

| District    | char(20) | NO   |     |         |                |

| Population  | int(11)  | NO   |     | 0       |                |

+-------------+----------+------+-----+---------+----------------+

5 rows in set (0.00 sec)

 

 

程序如下

 

// mysqlTest.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include "mysql.h"

 

 

#define MYSQL_PORT 3306

#define MYSQL_HOST "localhost"

#define MYSQL_USER "root"

#define MYSQL_PASSWD   "passwd"

#define MYSQL_DB   "world"

 

#define MYSQL_NAME_LEN 35

 

#define MYSQL_SELECTSTATEMENT    "select id, name from city where id=?"

 

 

 

int _tmain(int argc, _TCHAR* argv[])

{

 

     int result;

     MYSQL mySQLHandler;

     MYSQL_STMT *mySQLStmt;

     MYSQL_BIND mySQLBindInput;

     MYSQL_BIND mySQLBindOutput[2];

 

     int cityId=0;

     my_bool isNullInput = FALSE;

     my_bool isNullOutput[2];

     my_bool isUnsigned = TRUE;

     unsigned long length[2];

     my_bool err[2];

 

     int id;

     char name[MYSQL_NAME_LEN];

 

     mysql_library_init(0,NULL,NULL);

 

     mysql_init(&mySQLHandler);

 

     printf("1. inited ---------------\n");

 

     if (!mysql_real_connect(&mySQLHandler, MYSQL_HOST, MYSQL_USER, MYSQL_PASSWD, MYSQL_DB,MYSQL_PORT, NULL, 0))

     {

         printf( "Error connecting to database: %s\n",mysql_error(&mySQLHandler));

         exit(1);

     }

 

     printf("2. connected ---------------\n");

 

     mySQLStmt = mysql_stmt_init(&mySQLHandler);

 

     if (!mySQLStmt)   

     {

         printf( "stmt init err\n");

         exit(1);

     }

 

     printf(". stmt init ---------------\n");

 

     result = mysql_stmt_prepare(mySQLStmt, MYSQL_SELECTSTATEMENT, strlen(MYSQL_SELECTSTATEMENT));

     if (result)

     {

         printf( "Error stmt prepare: %s\n",mysql_error(&mySQLHandler));

         exit(1);

     }

 

     printf(". stmt prepare ---------------\n");

 

     while(1)

     {

         cityId++;

 

         memset(&mySQLBindInput, 0, sizeof(MYSQL_BIND));

 

 

         mySQLBindInput.buffer_type = MYSQL_TYPE_LONG;

         mySQLBindInput.buffer = &cityId;

//       mySQLBindInput.buffer_length = sizeof(cityId); // this is ignored by mysql because the type is numeric.

//       mySQLBindInput.length = 0; // this is ignored by mysql because the type is numeric.

         mySQLBindInput.is_null = 0;

 

         result = mysql_stmt_bind_param(mySQLStmt, &mySQLBindInput) ;

 

         if (result)

         {

              printf( "Error bind param: %s\n",mysql_error(&mySQLHandler));

              exit(1);

         }

 

//       printf(". bind param %d ---------------\n", cityId);

 

 

         result = mysql_stmt_execute(mySQLStmt);

         if (result)

         {

              printf( "Error execute: %s\n",mysql_error(&mySQLHandler));

              exit(1);

         }

 

//       printf(". Execute ---------------\n");

 

 

         memset(&mySQLBindOutput[0], 0, sizeof(MYSQL_BIND));

         memset(&mySQLBindOutput[1], 0, sizeof(MYSQL_BIND));

 

         mySQLBindOutput[0].buffer_type =MYSQL_TYPE_LONG;

         mySQLBindOutput[0].buffer = &id;

         mySQLBindOutput[0].buffer_length = sizeof(id); // this is ignored by mysql because the type is numeric.

         mySQLBindOutput[0].length =  &length[0];

         mySQLBindOutput[0].is_null = &isNullOutput[0];

         mySQLBindOutput[0].error = &err[0];

 

         mySQLBindOutput[1].buffer_type =MYSQL_TYPE_STRING;

         mySQLBindOutput[1].buffer = &name;

         mySQLBindOutput[1].buffer_length = MYSQL_NAME_LEN; // this is ignored by mysql because the type is numeric.

         mySQLBindOutput[1].length =  &length[1]; // this is ignored by mysql because the type is numeric.

         mySQLBindOutput[1].is_null = &isNullOutput[1];

         mySQLBindOutput[1].error = &err[1];

 

 

         result = mysql_stmt_bind_result(mySQLStmt, mySQLBindOutput);

         if (result)

         {

              printf( "Error bind result: %s\n",mysql_error(&mySQLHandler));

              exit(1);

         }

 

//       printf(". bind result ---------------\n");

 

         result = mysql_stmt_store_result(mySQLStmt);

 

         if (result)

         {

              printf( "Error store result: %s\n",mysql_error(&mySQLHandler));

              exit(1);

         }

 

//       printf(". store result ---------------\n");

 

//       printf(". fetching result ---------------\n");

 

         if(mysql_stmt_num_rows(mySQLStmt)==0)

              break;

 

         while(!mysql_stmt_fetch(mySQLStmt))

         {

              printf("id= %d, name= %s \n", isNullOutput[0]?0:id, isNullOutput[1]?0:name);

         }

     }

 

     printf(". fetch result over ---------------\n");

 

     mysql_stmt_close(mySQLStmt);

 

     printf(". stmt close ---------------\n");

 

     mysql_close(&mySQLHandler);

     printf("6.close mysql ---------------\n");

 

     mysql_library_end();

 

     return 0;

}

 

阅读(1620) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~