C++ Mysql 工程搭建及基本操作笔记
目录
mysql_real_connect数据库完成连接,以及超时重连设置
获取表字段及数量等信息 mysql_fetch_field,mysql_fetch_field_direct
C++ Mysql 工程搭建
- 工程目录结构
- 找到安装的mysql目录下的 include 和 lib,将其复制到代码工程目录下,这两个文件夹下有些不需要的可以删除。
- 比如lib中只需要
- 配置头文件路径:
- 库目录:
- 链接:
- 设置输出目录
- bin目录下需要添加相应的动态库,可以在mysql的bin目录下找到复制过来
- 测试代码:
#include <iostream>
#include "mysql.h"
int main()
{
MYSQL mysql;
mysql_info(&mysql);
std::cout << "Hello World!\n";
}
Mysql初始化
//初始化mysql上下文
//MYSQL mysql;
//单线程模式 mysql_init自动调用 线程不安全
mysql_library_init(0, 0, 0);
for (;;)
{
//方式1
//MYSQL mysql;
//mysql_init(&mysql);
//mysql_close(&mysql);
//方式2
//MYSQL *mysql = new MYSQL();
//mysql_init(mysql);
//mysql_close(mysql);
//delete mysql;
//方式3
MYSQL *mysql = mysql_init(0);
mysql_close(mysql);
}
mysql_library_end();
Mysql 连接及查询等基本操作
mysql_real_connect数据库完成连接,以及超时重连设置
#include "mysql.h"
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
//初始化mysql上下文
MYSQL mysql;
//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
mysql_init(&mysql);
const char *host = "127.0.0.1";
const char *user = "root";
const char *pass = "root";
const char *db = "cpptest"; //数据库名称
//设定超时3秒
int to = 3;
int re = mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, &to);
if (re != 0) {
std::cout << "mysql_options failed!" << mysql_error(&mysql) << std::endl;
}
//自动重连
int recon = 1;
re = mysql_options(&mysql, MYSQL_OPT_RECONNECT, &recon);
if (re != 0) {
std::cout << "mysql_options failed!" << mysql_error(&mysql) << std::endl;
}
if (!mysql_real_connect(&mysql, host, user, pass, db, 3306, 0, 0)) {
std::cout << "mysql connect failed!" << mysql_error(&mysql) << std::endl;
} else {
std::cout << "mysql connect success!" << std::endl;
}
for (int i = 0; i < 1000; i++) {
int re = mysql_ping(&mysql);
if (re == 0) {
std::cout << host << ":mysql ping success!" << std::endl;
} else {
std::cout << host << ":mysql ping failed! " << mysql_error(&mysql) << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
mysql_close(&mysql);
mysql_library_end();
}
语句查询示例
// user select * from test1
// 1 执行SQL语句
const char *sql = "select * from test1";
// mysql_real_query sql语句中可以包含二进制数据
// mysql_query sql语句中只能是字符串
// 0返回表示成功
int re = mysql_real_query(&mysql, sql, strlen(sql));
// Commands out of sync; you can't run this command now
// 执行sql语句后,必须获取结果集并且清理
// re = mysql_query(&mysql, sql);
if (re != 0) {
std::cout << "mysql_real_query faied! " << sql << " " << mysql_error(&mysql)
<< std::endl;
} else {
std::cout << "mysql_real_query success! " << sql << std::endl;
}
// 2 获取结果集
// mysql_use_result 不实际读取数据
// MYSQL_RES* result = mysql_use_result(&mysql);
// mysql_store_result 读取所有数据,注意缓存大小 MYSQL_OPT_MAX_ALLOWED_PACKET
// 默认 64M
MYSQL_RES *result = mysql_store_result(&mysql);
if (!result) {
std::cout << "mysql_use_result faied! " << mysql_error(&mysql) << std::endl;
}
// 3 遍历结果集
MYSQL_ROW row;
while (row = mysql_fetch_row(result)) {
unsigned long *lens = mysql_fetch_lengths(result);
std::cout << lens[1] << "[" << row[0] << "," << row[1] << "]" << std::endl;
}
//清理结果集
mysql_free_result(result);
获取表字段及数量等信息 mysql_fetch_field,mysql_fetch_field_direct
MYSQL_RES *result = mysql_store_result(&mysql);
if (!result) {
std::cout << "mysql_use_result faied! " << mysql_error(&mysql) << std::endl;
}
//获取表字段
MYSQL_FIELD *field = 0;
while (field = mysql_fetch_field(result)) {
std::cout << "key:" << field->name << std::endl;
}
//获取表字段数量
int fnum = mysql_num_fields(result);
std::cout << "fnum = " << fnum << std::endl;
// 3 遍历结果集
MYSQL_ROW row;
while (row = mysql_fetch_row(result)) {
unsigned long *lens = mysql_fetch_lengths(result);
for (int i = 0; i < fnum; i++) {
std::cout << mysql_fetch_field_direct(result, i)->name << ":";
if (row[i])
std::cout << row[i];
else
std::cout << "NULL";
std::cout << ",";
}
std::cout << "\n" << std::endl;
}
//清理结果集
mysql_free_result(result);
- 示例:
表格创建及数据增删改查
// 1 创建表
std::string sql = "";
sql ="CREATE TABLE IF NOT EXISTS `t_image` ( \
`id` int AUTO_INCREMENT,\
`name` varchar(1024),\
`path` varchar(2046),\
`size` int,\
PRIMARY KEY(`id`)\
) ";
int re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "CREATE TABLE failed!" << mysql_error(&mysql) << std::endl;
}
//清空数据,并恢复自增id从1开始
sql = "truncate t_image";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "truncate failed!" << mysql_error(&mysql) << std::endl;
}
// 2 插入数据 CLIENT_MULTI_STATEMENTS
for (int i = 0; i < 10; i++) {
// sql = "insert `t_image` (`name`,`path`,`size`)
// values('test.jpg','d:/img/test.jpg',10240)";
std::stringstream ss;
ss << "insert `t_image` (`name`,`path`,`size`) values('image";
ss << i << ".jpg','d:/img/', 10240)";
sql = ss.str();
re = mysql_query(&mysql, sql.c_str());
if (re == 0) {
int count = mysql_affected_rows(&mysql);
std::cout << "insert mysql_affected_rows " << count << std::endl;
} else {
std::cout << "insert failed!" << mysql_error(&mysql) << std::endl;
}
}
// 3 修改数据
// update t_image set `name`="test2.png",size=2000 where id=1
sql = "update t_image set `name`='test114514.png',size=2000 where id=1";
re = mysql_query(&mysql, sql.c_str());
if (re == 0) {
int count = mysql_affected_rows(&mysql);
std::cout << "update mysql_affected_rows " << count << std::endl;
} else {
std::cout << "update failed!" << mysql_error(&mysql) << std::endl;
}
//技巧:根据map自动生成 update sql语句
std::map<std::string, std::string> kv;
kv.insert(std::make_pair("name", "image_update001.png"));
kv.insert(std::make_pair("size", "5000"));
std::string where = " where id=2 ";
std::string tmp = "";
for (auto ptr = kv.begin(); ptr != kv.end(); ptr++) {
tmp += "`";
tmp += ptr->first;
tmp += "`='";
tmp += ptr->second;
tmp += "',";
}
tmp += " id=id ";
sql = "update t_image set ";
sql += tmp;
sql += where;
re = mysql_query(&mysql, sql.c_str());
if (re == 0) {
int count = mysql_affected_rows(&mysql);
std::cout << "update mysql_affected_rows " << count << std::endl;
} else {
std::cout << "update failed!" << mysql_error(&mysql) << std::endl;
}
// 4 删除数据
sql = "delete from t_image where id=1";
re = mysql_query(&mysql, sql.c_str());
if (re == 0) {
int count = mysql_affected_rows(&mysql);
std::cout << "delete mysql_affected_rows " << count << std::endl;
} else {
std::cout << "delete failed!" << mysql_error(&mysql) << std::endl;
}
// delete 不会实际删除空间,只做了标识
sql = "delete from t_image";
re = mysql_query(&mysql, sql.c_str());
if (re == 0) {
int count = mysql_affected_rows(&mysql);
std::cout << "delete mysql_affected_rows " << count << std::endl;
} else {
std::cout << "delete failed!" << mysql_error(&mysql) << std::endl;
}
//实际清理了空间,空闲时间进行操作
sql = "OPTIMIZE TABLE t_image";
re = mysql_query(&mysql, sql.c_str());
一次执行多条sql语句
//初始化mysql上下文
MYSQL mysql;
//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
mysql_init(&mysql);
const char *host = "127.0.0.1";
const char *user = "root";
const char *pass = "root";
const char *db = "cpptest"; //数据库名称
// CLIENT_MULTI_STATEMENTS 支持多条sql语句
if (!mysql_real_connect(&mysql, host, user, pass, db, 3306, 0,
CLIENT_MULTI_STATEMENTS))
{
std::cout << "mysql connect failed!" << mysql_error(&mysql) << std::endl;
} else {
std::cout << "mysql connect success!" << std::endl;
}
// 1 创建表
std::string sql =
"CREATE TABLE IF NOT EXISTS `t_image` ( \
`id` int AUTO_INCREMENT,\
`name` varchar(1024),\
`path` varchar(2046),\
`size` int,\
PRIMARY KEY(`id`)\
) ;";
//清空数据,并恢复自增id从1开始
sql += "truncate t_image;";
// 2 插入数据 CLIENT_MULTI_STATEMENTS
for (int i = 0; i < 100; i++) {
// sql = "insert `t_image` (`name`,`path`,`size`)
// values('test.jpg','d:/img/test.jpg',10240)";
std::stringstream ss;
ss << "insert `t_image` (`name`,`path`,`size`)values('image";
ss << i << ".jpg','d:/img/', 10240);";
sql += ss.str();
}
// 3 修改数据
// update t_image set `name`="test2.png",size=2000 where id=1
sql += "update t_image set `name`='test3.png',size=2000 where id=1;";
// 4 删除数据
sql += "delete from t_image where id=1;";
//查询结果
sql += "select * from t_image;";
//执行sql语句立刻返回,但语句并没有全部执行好,需要获取结果
//把sql整个发送给mysql server,server一条条执行,返回结果
int re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed!" << mysql_error(&mysql) << std::endl;
}
//有多个返回结果
do {
std::cout << "[result]";
MYSQL_RES *result = mysql_store_result(&mysql);
if (result) // SELECT
{
std::cout << "SELECT mysql_num_rows = " << mysql_num_rows(result)
<< std::endl;
mysql_free_result(result);
} else // INSERT UPDATE DELETE CREATE DROP truncate
{
// SELECT 出错 有字段无结果
if (mysql_field_count(&mysql) > 0) {
std::cout << "Not retrieve result! " << mysql_error(&mysql)
<< std::endl;
} else // INSERT UPDATE DELETE CREATE DROP truncate
{
//等待服务器的处理结果
std::cout << mysql_affected_rows(&mysql) << " rows affected!"
<< std::endl;
}
}
}//取下一条结果 0表示有结果
while (mysql_next_result(&mysql) == 0);
事务操作
//创建表
std::string sql =
"CREATE TABLE IF NOT EXISTS `t_video` ( \
`id` int AUTO_INCREMENT,\
`name` varchar(1024),\
`path` varchar(2046),\
`size` int,\
PRIMARY KEY(`id`)\
) ENGINE=InnoDB;"; //设置支持事务回滚的 InnoDB引擎
int re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
//清空数据,并恢复自增id从1开始
//清理表数据
sql = "truncate t_video";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
// 事务
// 1 开始事务
// START TRANSACTION;
sql = "START TRANSACTION";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
// 2 设置为手动提交事务
// set autocommit = 0
sql = "set autocommit = 0";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
// 3 sql语句
//插入三条数据,回滚
for (int i = 0; i < 3; i++) {
sql = "insert into t_video (name) values('test 111111!')";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
}
// 4 回滚ROLLBACK MYISAM 不支持
sql = "ROLLBACK";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
for (int i = 0; i < 1000; i++) {
sql = "insert into t_video (name) values('test three!')";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
}
// 5 COMMIT
sql = "COMMIT";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
// 6 恢复自动提交 set autocommit = 1
sql = "set autocommit = 1";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
//查询结果
sql = "select count(*) from t_video";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
MYSQL_RES *res = mysql_store_result(&mysql);
if (res) {
//取得第一行数据
MYSQL_ROW row = mysql_fetch_row(res);
if (row) {
std::cout << "t_video count(*) = " << row[0] << std::endl;
}
}
比较单条和多条SQL语句及事务插入十万条数据的性
auto start = std::chrono::system_clock::now();
//单条语句插入1千条数据
for (int i = 0; i < 1000; i++) {
sql =
"insert into t_video (name,path) "
"values('single','"
"01234567890123456789012345678901234567890123456789012345678901234567"
"89012345678901234567890123456789')";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
}
auto end = std::chrono::system_clock::now();
//转换为毫秒 1000
auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "1 单条语句插入1千条数据" << dur.count() / 1000. << "秒"
<< std::endl;
//多条语句插入1千条数据
{
auto start = std::chrono::system_clock::now();
sql = "";
//单条语句插入1千条数据
for (int i = 0; i < 1000; i++) {
sql +=
"insert into t_video (name,path) "
"values('single','"
"01234567890123456789012345678901234567890123456789012345678901234567"
"89012345678901234567890123456789');";
}
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
do {
//std::cout << mysql_affected_rows(&mysql) << std::flush;
mysql_affected_rows(&mysql);
} while (mysql_next_result(&mysql) == 0);
auto end = std::chrono::system_clock::now();
//转换为毫秒 1000
auto dur =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "2 多条语句插入1千条数据" << dur.count() / 1000. << "秒"
<< std::endl;
}
//事务插入1千条数据
{
// 1 开始事务
// START TRANSACTION;
sql = "START TRANSACTION";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
// 2 设置为手动提交事务
// set autocommit = 0
sql = "set autocommit = 0";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
auto start = std::chrono::system_clock::now();
//单条语句插入1千条数据
for (int i = 0; i < 1000; i++) {
sql =
"insert into t_video (name,path) "
"values('single','"
"01234567890123456789012345678901234567890123456789012345678901234567"
"89012345678901234567890123456789')";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
} else
//std::cout << mysql_affected_rows(&mysql) << std::flush;
mysql_affected_rows(&mysql);
}
sql = "COMMIT";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
sql = "set autocommit = 1";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << "mysql_query failed! " << mysql_error(&mysql) << std::endl;
}
auto end = std::chrono::system_clock::now();
//转换为毫秒 1000
auto dur =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "3 事务插入1千条数据" << dur.count() / 1000. << "秒"
<< std::endl;
}
- 结果:
二进制数据图片的读取并存储为文件
// mysqltest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "mysql.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <sstream>
#include <map>
#include <fstream>
int main()
{
//初始化mysql上下文
MYSQL mysql;
//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
mysql_init(&mysql);
const char *host = "127.0.0.1";
const char *user = "root";
const char *pass = "root";
const char *db = "cpptest"; //数据库名称
if (!mysql_real_connect(&mysql, host, user, pass, db, 3306, 0,
CLIENT_MULTI_STATEMENTS))
{
std::cout << "mysql connect failed!" << mysql_error(&mysql) << std::endl;
} else {
std::cout << "mysql connect success!" << std::endl;
}
// 1 创建好存放二进制数据的表 t_data
std::string sql =
"CREATE TABLE IF NOT EXISTS `t_data` (\
`id` int AUTO_INCREMENT,\
`name` varchar(1024),\
`data` blob,\
`size` int,\
PRIMARY KEY(`id`))";
int re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << mysql_error(&mysql) << std::endl;
}
// 2 清空表 truncate t_data
sql = "truncate t_data";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cerr << mysql_error(&mysql) << std::endl;
}
// 3 初始化stmt mysql_stmt_init
MYSQL_STMT *stmt = mysql_stmt_init(&mysql);
if (!stmt) {
std::cerr << "mysql_stmt_init failed!" << mysql_error(&mysql) << std::endl;
}
// 4 预处理sql语句
sql = "INSERT INTO `t_data` (name,data,size) VALUES(?,?,?)";
if (mysql_stmt_prepare(stmt, sql.c_str(), sql.size())) {
std::cerr << "mysql_stmt_prepare failed!" << mysql_stmt_error(stmt)
<< std::endl;
}
// 5 打开并读取文件
std::string filename = "mysql.jpg";
//读取二进制
std::fstream in(filename, std::ios::in | std::ios::binary);
if (!in.is_open()) {
std::cerr << "file " << filename << " open failed!" << std::endl;
return 1;
}
//文件指针移动到结尾处
in.seekg(0, std::ios::end);
//文件大小和文件二进制地址
unsigned int filesize = in.tellg();
//回到开头
in.seekg(0, std::ios::beg);
char *data = new char[filesize];
unsigned int readed = 0; //已经读了多少
while (!in.eof()) {
in.read(data + readed, filesize - readed);
//读取了多少字节
if (in.gcount() <= 0) break;
readed += in.gcount();
}
in.close();
// 6 绑定字段
MYSQL_BIND bind[3] = {0};
bind[0].buffer_type = MYSQL_TYPE_STRING; // name 文件名
bind[0].buffer = (char *)filename.c_str();
bind[0].buffer_length = filename.size();
bind[1].buffer_type = MYSQL_TYPE_BLOB; // data 文件二进制内容
bind[1].buffer = data; //二进制文件
bind[1].buffer_length = filesize;
//文件大小
bind[2].buffer_type = MYSQL_TYPE_LONG;
bind[2].buffer = &filesize;
if (mysql_stmt_bind_param(stmt, bind) != 0) {
std::cerr << "mysql_stmt_bind_param failed! " << mysql_stmt_error(stmt)
<< std::endl;
}
// 7 执行stmt sql
if (mysql_stmt_execute(stmt) != 0) {
std::cerr << "mysql_stmt_execute failed! " << mysql_stmt_error(stmt)
<< std::endl;
}
delete[] data;
mysql_stmt_close(stmt);
// 8 查询二进制数据,并保存问文件
sql = "select * from t_data";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cerr << "mysql query failed!" << mysql_error(&mysql) << std::endl;
}
//获取结果集
MYSQL_RES *res = mysql_store_result(&mysql);
if (!res) {
std::cerr << "mysql_store_result failed!" << mysql_error(&mysql)
<< std::endl;
}
//取一行数据
MYSQL_ROW row = mysql_fetch_row(res);
if (!row) {
std::cerr << "mysql_fetch_row failed!" << mysql_error(&mysql) << std::endl;
}
std::cout << row[0] << " " << row[1] << " " << row[3] << std::endl;
//获取每列数据的大小
unsigned long *lens = mysql_fetch_lengths(res);
int fnum = mysql_num_fields(res);
for (int i = 0; i < fnum; i++) {
std::cout << "[" << lens[i] << "]";
}
filename = "img_out_";
filename += row[1];
std::fstream out(filename, std::ios::out | std::ios::binary);
if (!out.is_open()) {
std::cerr << "open file " << filename << " failed!" << std::endl;
}
out.write(row[2], lens[2]);
out.close();
mysql_close(&mysql);
mysql_library_end();
}
创建存储过程
// mysqltest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "mysql.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <sstream>
#include <map>
#include <fstream>
int main()
{
//初始化mysql上下文
MYSQL mysql;
//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
mysql_init(&mysql);
const char *host = "127.0.0.1";
const char *user = "root";
const char *pass = "root";
const char *db = "cpptest"; //数据库名称
if (!mysql_real_connect(&mysql, host, user, pass, db, 3306, 0,
CLIENT_MULTI_STATEMENTS))
{
std::cout << "mysql connect failed!" << mysql_error(&mysql) << std::endl;
} else {
std::cout << "mysql connect success!" << std::endl;
}
std::string sql;
// 1 创建存储过程
sql =
"CREATE PROCEDURE `p_test` (IN p_in INT,OUT p_out INT,INOUT p_inout INT)\
BEGIN\
SELECT p_in,p_out,p_inout;\
SET p_in = 100, p_out = 200,p_inout=300; \
SELECT p_in,p_out,p_inout;\
END";
int re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << mysql_error(&mysql) << std::endl;
}
// 2 定义变量并复制
std::cout << "IN in=1 out=2 inout=3" << std::endl;
sql = "SET @A=1;SET @B=2;SET @C=3;";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << mysql_error(&mysql) << std::endl;
}
do {
std::cout << "SET affect " << mysql_affected_rows(&mysql) << std::endl;
}
// 0 还有结果, -1 没有结果 >1错误
while (mysql_next_result(&mysql) == 0);
// 3 调用存储过程 call
sql = "call p_test(@A,@B,@C)";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << mysql_error(&mysql) << std::endl;
}
std::cout << "In Proc:";
do {
MYSQL_RES *res = mysql_store_result(&mysql);
if (!res) continue;
//字段数量
int fcount = mysql_num_fields(res);
//打印结果集
for (;;) {
//提取一行记录
MYSQL_ROW row = mysql_fetch_row(res);
if (!row) break;
for (int i = 0; i < fcount; i++) {
if (row[i]) {
std::cout << row[i] << " ";
} else
std::cout << "NULL"
<< " ";
}
std::cout << std::endl;
}
mysql_free_result(res);
}
// 0 还有结果, -1 没有结果 >1错误
while (mysql_next_result(&mysql) == 0);
// 4 获取存储过程的结果
sql = "select @A,@B,@C";
re = mysql_query(&mysql, sql.c_str());
if (re != 0) {
std::cout << mysql_error(&mysql) << std::endl;
}
MYSQL_RES *res = mysql_store_result(&mysql);
std::cout << "out: ";
MYSQL_ROW row = mysql_fetch_row(res);
std::cout << " in=" << row[0];
std::cout << " out=" << row[1];
std::cout << " inout=" << row[2];
mysql_free_result(res);
std::cout << std::endl;
mysql_close(&mysql);
mysql_library_end();
}
- 结果: