mysql statement 操作

mysql statement 基本操作

概述

MySQL客户端/服务器协议提供了预处理语句。该功能采用了由mysql_stmt_init()初始化函数返回的MYSQL_STMT语句处理程序数据结构。对于多次执行的语句,预处理执行是一种有效的方式。首先对语句进行解析,为执行作好准备。接下来,在以后使用初始化函数返回的语句句柄执行一次或多次。

对于多次执行的语句,预处理执行比直接执行快,主要原因在于,仅对查询执行一次解析操作。在直接执行的情况下,每次执行语句时,均将进行查询。此外,由于每次执行预处理语句时仅需发送参数的数据,从而减少了网络通信量。

预处理语句的另一个优点是,它采用了二进制协议,从而使得客户端和服务器之间的数据传输更有效率。

下述语句可用作预处理语句:CREATE TABLE、DELETE、DO、INSERT、REPLACE、SELECT、SET、UPDATE、以及大多数SHOW语句。在MySQL 5.1中,不支持其他语句。

mysql statement基本操作接口

mysql_stmt_init()

  • 描述

    MYSQL_STMT *mysql_stmt_init(MYSQL *mysql)

    创建MYSQL_STMT句柄。对于该句柄,应使用mysql_stmt_close(MYSQL_STMT *)释放。

  • 返回值

    成功时,返回指向MYSQL_STMT结构的指针。如果内存溢出,返回NULL。

  • 错误

    CR_OUT_OF_MEMORY 内存溢出

mysql_stmt_prepare()

  • 描述

    int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length)

    给定mysql_stmt_init()返回的语句句柄,准备字符串查询指向的SQL语句,并返回状态值。字符串长度应由“length”参量给出。字符串必须包含1条SQL语句。不应为语句添加终结用分号(‘;’)或\g。

    通过将问号字符“?”嵌入到SQL字符串的恰当位置,应用程序可包含SQL语句中的一个或多个参数标记符。

    标记符仅在SQL语句中的特定位置时才是合法的。例如,它可以在INSERT语句的VALUES()列表中(为行指定列值),或与WHERE子句中某列的比较部分(用以指定比较值)。但是,对于ID(例如表名或列名),不允许使用它们,不允许指定二进制操作符(如等于号“=”)的操作数。后一个限制是有必要的,原因在于,无法确定参数类型。一般而言,参数仅在DML(数据操作语言)语句中才是合法的,在DDL(数据定义语言)语句中不合法。

    执行语句之前,必须使用mysql_stmt_bind_param(),将参数标记符与应用程序变量绑定在一起。

    如果准备操作失败(即mysql_stmt_prepare()返回非0值),可通过调用mysql_stmt_error()获取错误消息。

  • 返回值

    如果成功处理了语句,返回0。如果出现错误,返回非0值。

  • 错误

    错误码错误描述
    CR_COMMANDS_OUT_OF_SYNC以不恰当的顺序执行了命令
    CR_OUT_OF_MEMORY内存溢出
    CR_SERVER_GONE_ERRORMySQL服务器不可用
    CR_SERVER_LOST查询过程中,与服务器的连接丢失
    CR_UNKNOWN_ERROR出现未知错误

mysql_stmt_bind_param()

  • 描述

    my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)

    mysql_stmt_bind_param()用于为SQL语句中的参数标记符绑定数据,以传递给mysql_stmt_prepare()。它使用MYSQL_BIND结构来提供数据。“bind”是MYSQL_BIND结构的某一数组的地址。按照客户端库的预期,对于查询中出现的每个“?”参数标记符,数组中均包含1个元素。

    假定你准备了下述语句:

    INSERT INTO mytbl VALUES(?,?,?)
    

    绑定参数时,MYSQL_BIND结构的数组包含3个元素,并能声明如下:

    MYSQL_BIND bind[3];
    
  • 返回值

    如果绑定成功,返回0。如果出现错误,返回非0值。

  • 错误码

    错误码错误提示
    CR_INVALID_BUFFER_USE指明“bind”(绑定)是否将提供程序块中的长数据,以及缓冲类型是否为非字符串或二进制类型
    CR_UNSUPPORTED_PARAM_TYPE不支持该转换。或许buffer_type值是非法的,或不是所支持的类型之一
    CR_OUT_OF_MEMORY内存溢出
    CR_UNKNOWN_ERROR未知错误

mysql_stmt_bind_result()

  • 描述

    my_bool mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)

    mysql_stmt_bind_result()用于将结果集中的列与数据缓冲和长度缓冲关联(绑定)起来。当调用mysql_stmt_fetch()以获取数据时,MySQL客户端/服务器协议会将绑定列的数据置于指定的缓冲区内。

    调用mysql_stmt_fetch()之前,必须将所有列绑定到缓冲。“bind”是MYSQL_BIND结构某一数组的地址。按照客户端库的预期,对于结果集中的每一列,数组应包含相应的元素。如果未将列绑定到MYSQL_BIND结构,mysql_stmt_fetch()将简单地忽略数据获取操作。缓冲区应足够大,足以容纳数据值,这是因为协议不返回成块的数据值。

    可以在任何时候绑定或再绑定列,即使已部分检索了结果集后也同样。新的绑定将在下一次调用mysql_stmt_fetch()时起作用。假定某一应用程序绑定了结果集中的列,并调用了mysql_stmt_fetch()。客户端/服务器协议将返回绑定缓冲区中的数据。接下来,假定应用程序将多个列绑定到不同的缓冲。该协议不会将数据置于新绑定的缓冲区,直至下次调用mysql_stmt_fetch()为止。

  • 返回值 (mysql_stmt_bind_param)

*int mysql_stmt_execute(MYSQL_STMT stmt)

  • 描述

    mysql_stmt_execute()执行与语句句柄相关的预处理查询。在该调用期间,将当前绑定的参数标记符的值发送到服务器,服务器用新提供的数据替换标记符。

    如果语句是UPDATE、DELETE或INSERT,通过调用mysql_stmt_affected_rows(),可发现更改、删除或插入的总行数。如果这是诸如SELECT等能生成结果集的语句,调用任何其他能导致查询处理的函数之前,必须调用mysql_stmt_fetch()来获取数据。

    对于生成结果集的语句,执行语句之前,可通过调用mysql_stmt_attr_set(),请求mysql_stmt_execute()为语句打开光标。如果多次执行某一语句,在打开新的光标前,mysql_stmt_execute()将关闭任何已打开的光标。

  • 返回值及错误码

    如果执行成功,返回0。如果出现错误,返回非0值。

    错误码错误描述
    CR_COMMANDS_OUT_OF_SYNC以不恰当的顺序执行了命令
    CR_OUT_OF_MEMORY内存溢出
    CR_SERVER_GONE_ERRORMySQL服务器不可用
    CR_SERVER_LOST在查询过程中,与服务器的连接丢失
    CR_UNKNOWN_ERROR出现未知错误

*int mysql_stmt_fetch(MYSQL_STMT stmt)

  • 描述

    mysql_stmt_fetch()返回结果集中的下一行。仅能当结果集存在时调用它,也就是说,调用了能创建结果集的mysql_stmt_execute()之后,或当mysql_stmt_execute()对整个结果集即行缓冲处理后调用了mysql_stmt_store_result()。

    使用mysql_stmt_bind_result()绑定的缓冲,mysql_stmt_fetch()返回行数据。对于当前列集合中的所有列,它将返回缓冲内的数据,并将长度返回到长度指针。

    调用mysql_stmt_fetch()之前,应用程序必须绑定所有列。

参考文献

示例

#include <iostream>
#include <queue>
#include <winsock.h>
#include <mysql.h>

#pragma comment(lib,"wsock32.lib") 
using namespace std;

const char* HOST = "127.0.0.1";
const char* USER = "root";
const char* PSW = "adminroot";
const char* DB = "sakila";
const int PORT = 3306;

struct ActorResult
{
	short actor_id;
	char first_name[64];
	char last_name[64];
	union 
	{
		char last_update[24];
		struct 
		{
			int year;
			int month;
			int day;
			int hour;
			int min;
			int sec;
		};

	};
	
};


int main()
{
	MYSQL sqlHandler;
	mysql_init(&sqlHandler);

	//返回false则连接失败,返回true则连接成功  
	if (!(mysql_real_connect(&sqlHandler, HOST, USER, PSW, DB, PORT, NULL, 0)))
		//中间分别是主机,用户名,密码,数据库名,端口号(可以写默认0或者3306等),可以先写成参数再传进去  
	{
		printf("Error connecting to database:%s\n", mysql_error(&sqlHandler));
		return 0;
	}
	printf("Connected...\n");
	mysql_set_character_set(&sqlHandler, "utf8");

	MYSQL_BIND sqlParam[10];
	MYSQL_BIND sqlResult[10];
	MYSQL_STMT* pStmtHandler = mysql_stmt_init(&sqlHandler);

	const char* sql = "select * from actor where actor_id < ?";
	mysql_stmt_prepare(pStmtHandler, sql, (unsigned long)strlen(sql));
	cout<< pStmtHandler->field_count << endl;
	pStmtHandler->param_count;

	//绑定参数
	int actor_id = 10;
	memset(sqlParam, 0, sizeof(sqlParam));
	sqlParam[0].buffer_type = MYSQL_TYPE_SHORT;
	sqlParam[0].buffer = &actor_id;
	mysql_stmt_bind_param(pStmtHandler, sqlParam);

	//绑定结果
	ActorResult actorResult;
	memset(&actorResult, 0, sizeof(actorResult));

	memset(sqlResult, 0, sizeof(sqlResult));
	sqlResult[0].buffer_type = MYSQL_TYPE_SHORT;
	sqlResult[0].buffer = &(actorResult.actor_id);
	sqlResult[1].buffer_type = MYSQL_TYPE_VAR_STRING;
	sqlResult[1].buffer = actorResult.first_name;
	sqlResult[1].buffer_length = 64;
	sqlResult[2].buffer_type = MYSQL_TYPE_VAR_STRING;
	sqlResult[2].buffer = actorResult.last_name;
	sqlResult[2].buffer_length = 64;
	sqlResult[3].buffer_type = MYSQL_TYPE_TIMESTAMP;
	sqlResult[3].buffer = actorResult.last_update;
	int ret = mysql_stmt_bind_result(pStmtHandler, sqlResult);
	if (ret != 0)
	{
		int error = mysql_stmt_errno(pStmtHandler);
	}

	//执行sql
	mysql_stmt_execute(pStmtHandler);
	mysql_stmt_store_result(pStmtHandler);
	int rows = mysql_stmt_num_rows(pStmtHandler);
	while ((ret = mysql_stmt_fetch(pStmtHandler)) == 0)
	{
		cout << actorResult.actor_id <<endl;
	}
	cout<< ret <<endl;

	getchar();


	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值