免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3213 | 回复: 0

MySql 100106:Connector/C (II) [复制链接]

论坛徽章:
0
发表于 2010-01-06 16:23 |显示全部楼层


  Normal
  0
  
  7.8 磅
  0
  2
  
  false
  false
  false
  
   
   
   
   
   
   
   
   
   
   
   
   
  
  MicrosoftInternetExplorer4



/* Style Definitions */
table.MsoNormalTable
        {mso-style-name:普通表格;
        mso-tstyle-rowband-size:0;
        mso-tstyle-colband-size:0;
        mso-style-noshow:yes;
        mso-style-parent:"";
        mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
        mso-para-margin:0cm;
        mso-para-margin-bottom:.0001pt;
        mso-pagination:widow-orphan;
        font-size:10.0pt;
        font-family:"Times New Roman";
        mso-ansi-language:#0400;
        mso-fareast-language:#0400;
        mso-bidi-language:#0400;}
table.MsoTableGrid
        {mso-style-name:网格型;
        mso-tstyle-rowband-size:0;
        mso-tstyle-colband-size:0;
        border:solid windowtext 1.0pt;
        mso-border-alt:solid windowtext .5pt;
        mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
        mso-border-insideh:.5pt solid windowtext;
        mso-border-insidev:.5pt solid windowtext;
        mso-para-margin:0cm;
        mso-para-margin-bottom:.0001pt;
        text-align:justify;
        text-justify:inter-ideograph;
        mso-pagination:none;
        font-size:10.0pt;
        font-family:"Times New Roman";
        mso-ansi-language:#0400;
        mso-fareast-language:#0400;
        mso-bidi-language:#0400;}
MySql 100106:Connector/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,使用完后应该close。stmt handle与 数据库连接(connection)的关系是多对一的关系。

3.主要数据结构
1) MYSQL_STMT
stmt handle的机构,代表一个prepared语句。mysql_stmt_init()生成,mysql_stmt_close()注销。

2)MYSQL_BIND
用于给定输入的语句参数,和输出的结果。使用前应当用0初始化。语句中参数使用'?'占位。
其中几个重要的域

  
  field
  
  
  input(bind 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有特别的用途。
  


3)MYSQL_TIME
用于表示DATE,TIME,DATETIME和TIMESTAMP。
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;
}

               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/8866/showart_2142337.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP