FarelDB 关系数据库命令 数据库操作类(database) 之 高性能批量更行 Update
高性能批量更新用于需要快速的批量更新大量数据的应用场景,该命令仅能被API接口调用。
API 说明
函数原型
FarelDbRes* batchUpdate(std::string dbName, std::string tableName, uint64_t rowCount, std::vectorstd::vectorstd::string> >& keyLists, std::vectorstd::string>& updateFieldNames, const char* updateRowDatas, uint64_t updateDataLen, int updateType = FARELDB_BATCHUPDATE_IGNORE_AFTER_KEY_NOT_EXISTS); |
---|
输入参数说明
输入参数 | 类型 | 描述 | 可选 |
---|---|---|---|
dbName | 字符串 | 操作表所属数据名称 | 否 |
tableName | 字符串 | 操作表名称 | 否 |
rowCount | 无符号8字节整型 | 批量更新的行数 | 否 |
keyLists | 二维数组向量 | 需要更新的行的行主键值 | 否 |
updateFieldNames | 一维度数组向量 | 需要更新的列的列名 | 否 |
updateRowDatas | 字符串指针 | 批量更新的所有数据 | 否 |
updateDataLen | 无符号整型 | 批量更新的所有数据长度 | 否 |
updateType | 整型(枚举) | 更新方式 | 否 |
updateType 更新方式说明:
插入方式(枚举) | 含义说明 |
---|---|
FARELDB_BATCHUPDATE_IGNORE_AFTER_KEY_NOT_EXISTS | 遇到键值不存在时,继续更新下一条记录,最后返回全部键值不存在信息 |
FARELDB_BATCHUPDATE_STOP_AFTER_KEY_NOT_EXISTS | 遇到键值不存在时,停止更新,返回键值不存在信息 |
返回参数说明
调用成功返回
返回参数 | 值 | 含义 |
---|---|---|
FarelDbRes->errorInfos.size() | 0 | 调用成功,无错误信息 |
调用异常返回
返回参数 | 值 | 含义 |
---|---|---|
FarelDbRes->errorInfos.size() | 大于0 | 调用失败,errorInfos对象数组包含1个或多个错误信息 |
FarelDbRes->errorInfos[0]->resCode | 大于0的数值 | 调用失败,返回错误代码 |
FarelDbRes->errorInfos[0]->resInfo | 非空字符串 | 调用失败,返回错误信息字符串 |
返回数据获取方法参考样例代码
样例代码
#include <iostream>
#include <functional>
#include <memory>
#include "fareldb_connection.h"
using namespace std;
using namespace fareldb_connection;
int main(int argc,char *argv[])
{
//创建连接
FarelDbConnection conn;
//连接
std::tuple<int, string> resConn = conn.connect("127.0.0.1", 6800, "root", "root");
//连接失败
if (0 != get<0>(resConn))
{
printf("连接失败,错误代码:%d : 错误信息:%s\n", get<0>(resConn), get<1>(resConn).c_str());
return;
}
//连接成功,可以开始进行后续操作
/*以学生表为例子
// 以Student 学生基本信息表为例 \
create table studentDB.student( \
ID int primary key auto_increment comment '学号ID(自增长列)', \
Name varchar(64) not null comment '姓名', \
Age int unsigned default 21 comment '年龄(无符号整型)', \
Gender short comment '性别: 1 男性 0 女性', \
Enrollment_Date TimeStamp default 1598889600000 comment '入学时间:2020-09-01(存储自1970年1月1日0点以来的毫秒数)', \
Score float default 660.6 comment '入学成绩', \
Scholarship double default 0 comment '奖学金', \
ID_Photo blob(1024) comment '证件照片', \
Note text default '备注说明' comment '备注说明' \
) ";
调用批量插入接口例子后表中包括数据如下:
FarelDb 192.168.56.1:6800 > select * from student
ID Name Age Gender Enrollment_Date Score Scholarship ID_Photo Note
0 Bob_0 0 0 2020-01-01 08:00:00.000 0.0000000 0.000 0 ""
1 Bob_1 1 1 2020-01-01 08:00:01.000 1.0010000 1.001 1 ""
2 Bob_2 2 0 2020-01-01 08:00:02.000 2.0020001 2.002 2 ""
3 Bob_3 3 1 2020-01-01 08:00:03.000 3.0030000 3.003 3 ""
4 Bob_4 4 0 2020-01-01 08:00:04.000 4.0040002 4.004 4 ""
5 Bob_5 5 1 2020-01-01 08:00:05.000 5.0050001 5.005 5 ""
6 Bob_6 6 0 2020-01-01 08:00:06.000 6.0060000 6.006 6 ""
7 Bob_7 7 1 2020-01-01 08:00:07.000 7.0070000 7.007 7 ""
8 Bob_8 8 0 2020-01-01 08:00:08.000 8.0080004 8.007 8 ""
9 Bob_9 9 1 2020-01-01 08:00:09.000 9.0089998 9.009 9 ""
[10 rows]
// 利用批量更新接口更新数据。目标:将ID等于1,3,4,5的行数据中Scholarship(奖学金)都改为1000元,Age(年龄)都改为20
*/
//第1步. 根据主键ID确定批量更新的行数
uint64_t rowCount = 4; //更新ID等于1,3,4,5的行,共4行
//第2步.传入更新行的主键信息
vector<vector<string> > keyLists;
vector<string> IDKeyValue;
IDKeyValue.clear();
IDKeyValue.emplace_back("1"); //所有主键以字符串传入
keyLists.emplace_back(IDKeyValue);
IDKeyValue.clear();
IDKeyValue.emplace_back("3"); //所有主键以字符串传入
keyLists.emplace_back(IDKeyValue);
IDKeyValue.clear();
IDKeyValue.emplace_back("4"); //所有主键以字符串传入
keyLists.emplace_back(IDKeyValue);
IDKeyValue.clear();
IDKeyValue.emplace_back("5"); //所有主键以字符串传入
keyLists.emplace_back(IDKeyValue);
//本例中student只有一个主键,即ID,如果更新行的主键存在多个(联合主键),则按照下面例子以此插入keyLists即可。
//vector<string> OthersKeyValue;
//OthersKeyValue.clear();
//OthersKeyValue.emplace_back("a"); //所有主键以字符串传入
//keyLists.emplace_back(OthersKeyValue);
//OthersKeyValue.clear();
//OthersKeyValue.emplace_back("b"); //所有主键以字符串传入
//keyLists.emplace_back(OthersKeyValue);
//OthersKeyValue.clear();
//OthersKeyValue.emplace_back("c"); //所有主键以字符串传入
//keyLists.emplace_back(OthersKeyValue);
//OthersKeyValue.clear();
//OthersKeyValue.emplace_back("d"); //所有主键以字符串传入
//keyLists.emplace_back(OthersKeyValue);
//第3步. 传入更新列的列信息
std::vector<std::string> updateFieldNames;
updateFieldNames.emplace_back("Scholarship");
updateFieldNames.emplace_back("Age");
//第4步. 传入更新数据
//第4.1步. 确定更新ID等于1,3,5,7的行的Scholarship(double类型)和Age(int类型)数据长度
uint64_t updateDataLen = rowCount * (sizeof(double) + sizeof(int));
//第4.2步. 申请空间
char* updateRowDatas = new char[updateDataLen];
memset(updateRowDatas, 0, updateDataLen);
//第4.3步. 填充数据,注意,这里必须按照第3步传入更新列的列信息的顺序填充数据
uint64_t offset = 0;
for (int i = 0; i < rowCount; i++)
{
double Scholarship = 1000;
FarelDbConnection::setValToBytes(Scholarship, updateRowDatas, offset);
offset += sizeof(double);
int Age = 20;
FarelDbConnection::setValToBytes(Age, updateRowDatas, offset);
offset += sizeof(int);
}
//第5步 调用批量更新接口
std::shared_ptr<FarelDbRes> res(conn.batchUpdate("studentDB", "student", rowCount, keyLists, updateFieldNames,updateRowDatas, updateDataLen, FARELDB_BATCHUPDATE_IGNORE_AFTER_KEY_NOT_EXISTS));
//判断执行命令返回是否失败
if (res->errorInfos.size() > 0)
{
printf("batchUpdate 调用失败,错误代码:%d ; 错误信息: %s \n\n", res->errorInfos[0]->resCode, res->errorInfos[0]->resInfo.c_str());
return;
}
printf("batchUpdate 调用成功 \n\n");
//最后一步,切记释放动态申请内存,防止内存泄漏
delete[] updateRowDatas;
updateRowDatas = nullptr;
}
补充说明:
- 方括号 [ ]
方括号 ( [ ] ) 表示里面的元素(参数、值或信息)是可选的。 您可以选择一个或多个条目,也可以不选。 不要将方括号本身也输入到命令行中。 - 尖括号 < >
尖括号 ( < > ) 表示里面的元素(参数、值或信息)是必需的。 您需要用相应的信息来替换尖括号里面的文本。 不要将尖括号本身也输入到命令行中。 - [ ,…n ] 表示前面的项可重复 n 次。每一项由逗号分隔。
- [ …n ] 表示前面的项可重复 n 次。每一项由空格分隔。
- | (竖线) 分隔括号或大括号内的语法项目。只能选择一个项目。