fang.zhang 发表于 2010-01-06 16:23

MySql 100106:Connector/C (II)



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;

   int
cityId=0;
   my_bool isNullInput = FALSE;
   my_bool isNullOutput;
   my_bool isUnsigned = TRUE;
   unsigned
long length;
   my_bool err;

   int
id;
   char
name;

   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, sizeof(MYSQL_BIND));
         memset(&mySQLBindOutput,
0, sizeof(MYSQL_BIND));

         mySQLBindOutput.buffer_type
=MYSQL_TYPE_LONG;
         mySQLBindOutput.buffer =
&id;
         mySQLBindOutput.buffer_length
= sizeof(id); // this
is ignored by mysql because the type is numeric.
         mySQLBindOutput.length
=&length;
         mySQLBindOutput.is_null =
&isNullOutput;
         mySQLBindOutput.error =
&err;

         mySQLBindOutput.buffer_type
=MYSQL_TYPE_STRING;
         mySQLBindOutput.buffer =
&name;
         mySQLBindOutput.buffer_length
= MYSQL_NAME_LEN; // this is ignored by mysql because
the type is numeric.
         mySQLBindOutput.length
=&length; // this is ignored by mysql because the type is numeric.
         mySQLBindOutput.is_null =
&isNullOutput;
         mySQLBindOutput.error =
&err;


         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:id, isNullOutput?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
页: [1]
查看完整版本: MySql 100106:Connector/C (II)