业务场景中使用 SQL 实现快速数据更新与插入
一、业务背景
在气象数据处理系统中,我们经常需要对分钟级的降水数据进行更新和插入操作。具体场景如下:
• 数据源会定期发送分钟级的降水数据,包括降水值(PRECA
)和质控码(PRECA_QC2
)。
• 如果系统中已存在对应时间点的数据,则需要更新降水值和质控码。
• 如果系统中不存在对应时间点的数据,则需要插入新的记录。
二、SQL 实现方法
为了高效地实现上述需求,我们采用INSERT INTO ... ON DUPLICATE KEY UPDATE
语法。这种方法可以在尝试插入数据时,自动检测是否存在冲突(如主键或唯一键冲突),并在冲突发生时执行更新操作。
1.数据表结构
假设数据表名为pre_YPREC00_N01
,其结构如下:
• pre_time
:时间戳,主键或唯一键,格式为YYYY-MM-DD HH:MM:SS
。
• PRECA
:降水值,类型为浮点数。
• PRECA_QC2
:质控码,类型为整数。
2.SQL 语句构造
插入并更新的 SQL 语句
INSERT INTO pre_YPREC00_N01 (pre_time, PRECA, PRECA_QC2)
VALUES
('2025-05-23 13:21:00', 0.1, 4),
('2025-05-23 13:22:00', 0.1, 4),
('2025-05-23 13:23:00', 0.1, 4),
('2025-05-23 13:24:00', 0.1, 4),
('2025-05-23 13:25:00', 0.1, 4),
('2025-05-23 13:26:00', 0.1, 4),
('2025-05-23 13:31:00', 0.1, 4),
('2025-05-23 13:32:00', 0.1, 4),
('2025-05-23 13:33:00', 0.1, 4),
('2025-05-23 13:34:00', 0.1, 4),
('2025-05-23 13:35:00', 0.1, 4),
('2025-05-23 13:36:00', 0.1, 4)
ON DUPLICATE KEY UPDATE
PRECA = VALUES(PRECA),
PRECA_QC2 = VALUES(PRECA_QC2);
3.代码实现
以下是使用 C++和 MySQL 的示例代码,展示如何动态生成上述 SQL 语句并执行:
#include <iostream>
#include <string>
#include <vector>
#include <mysql/mysql.h>// 假设 request 是一个包含分钟级数据的对象
struct MinuteData {std::string minute; // 时间戳,格式为 YYYY-MM-DD HH:MM:SSstd::string v; // 降水值std::string qc; // 质控码
};struct Request {std::vector<MinuteData> minutelist;
};void SetRainDataInDB(const Request& request, const std::string& strTableName) {int totalUpdates = request.minutelist.size();std::string strSqlBase = "INSERT INTO pre_" + strTableName + " (pre_time, PRECA, PRECA_QC2) VALUES ";std::string strSqlValues;for (size_t i = 0; i < totalUpdates; i++) {if (request.minutelist[i].v.empty()) {continue;}std::cout << "打印 订正的 [" << request.minutelist[i].minute << "] 分钟的 降水数据 [" << request.minutelist[i].v << "] 质控值 是[" << request.minutelist[i].qc << "]" << std::endl;strSqlValues += "('" + request.minutelist[i].minute + "', " + request.minutelist[i].v + ", 4), ";}// 去掉最后一个逗号if (!strSqlValues.empty()) {strSqlValues.pop_back();strSqlValues.pop_back(); // 去掉多余的逗号和空格}std::string strSqlOnDuplicateKeyUpdate = " ON DUPLICATE KEY UPDATE PRECA = VALUES(PRECA), PRECA_QC2 = VALUES(PRECA_QC2)";std::string strFullSQL = strSqlBase + strSqlValues + strSqlOnDuplicateKeyUpdate;std::cout << "SetRainDataInDB SQL: [" << strFullSQL << "]" << std::endl;// 连接数据库并执行 SQL 语句MYSQL* conn = mysql_init(NULL);if (mysql_real_connect(conn, "localhost", "username", "password", "database_name", 0, NULL, 0)) {if (mysql_query(conn, strFullSQL.c_str())) {std::cerr << "SQL 执行失败: " << mysql_error(conn) << std::endl;} else {std::cout << "SQL 执行成功" << std::endl;}mysql_close(conn);} else {std::cerr << "数据库连接失败: " << mysql_error(conn) << std::endl;}
}int main() {Request request;request.minutelist.push_back({"2025-05-23 13:21:00", "0.1", "4"});request.minutelist.push_back({"2025-05-23 13:22:00", "0.1", "4"});request.minutelist.push_back({"2025-05-23 13:23:00", "0.1", "4"});// 添加更多分钟级数据...SetRainDataInDB(request, "YPREC00_N01");return 0;
}
三、使用步骤
• 准备数据:
• 确保你有一个包含分钟级降水数据的数据源,数据格式应包括时间戳、降水值和质控码。
• 配置数据库:
• 确保数据库中存在目标表(如pre_YPREC00_N01
),并且pre_time
列是主键或唯一键。
• 运行代码:
• 将上述代码编译并运行,确保数据库连接信息正确。
• 代码将自动构造并执行 SQL 语句,实现数据的插入或更新。
四、注意事项
• 性能优化:
• 如果数据量较大,建议分批处理数据,避免一次性插入过多记录导致性能问题。
• 错误处理:
• 在实际应用中,应添加更详细的错误处理逻辑,确保系统在遇到异常时能够正确响应。
• 安全性:
• 避免 SQL 注入风险,确保输入数据经过适当的验证和转义。
通过上述方法,你可以快速实现气象数据的插入和更新操作,提高数据处理的效率和准确性。
相关文章:
业务场景中使用 SQL 实现快速数据更新与插入
一、业务背景 在气象数据处理系统中,我们经常需要对分钟级的降水数据进行更新和插入操作。具体场景如下: • 数据源会定期发送分钟级的降水数据,包括降水值(PRECA)和质控码(PRECA_QC2)。 • …...

QT之INI、JSON、XML处理
文章目录 INI文件处理写配置文件读配置文件 JSON 文件处理写入JSON读取JSON XML文件处理写XML文件读XML文件 INI文件处理 首先得引入QSettings QSettings 是用来存储和读取应用程序设置的一个类 #include "wrinifile.h"#include <QSettings> #include <QtD…...

微信小程序调用蓝牙API “wx.writeBLECharacteristicValue()“ 报 errCode: 10008 的解决方案
1、问题现象 问题:在开发微信小程序蓝牙通信功能时,常常会遇到莫名其妙的错误,查阅官方文档可能也无法找到答案。如在写入蓝牙数据时,报了这样的错误: {errno: 1500104, errCode: 10008, errMsg: "writeBLECharacteristicValue:fail:system error, status: UNKNOW…...

【Java基础笔记vlog】Java中常见的几种数组排序算法汇总详解
Java中常见的几种排序算法: 冒泡排序(Bubble Sort)选择排序(Selection Sort)插入排序(Insertion Sort)希尔排序(Shell Sort)归并排序(Merge Sort)…...

WebRTC与RTSP|RTMP的技术对比:低延迟与稳定性如何决定音视频直播的未来
引言 音视频直播技术已经深刻影响了我们的生活方式,尤其是在教育、医疗、安防、娱乐等行业中,音视频技术成为了行业发展的重要推动力。近年来,WebRTC作为一种开源的实时通信技术,成为了音视频领域的重要选择,它使得浏览…...

spring cloud alibaba Sentinel详解
spring cloud alibaba Sentinel详解 spring cloud alibaba Sentinel介绍 Sentinel 是阿里巴巴开源的一款动态流量控制组件,主要用于保障微服务架构中的服务稳定性。它能够对微服务中的各种资源(如接口、服务方法等)进行实时监控、流量控制、…...
Kafka + Flink + Spark 构建实时数仓全链路实战
本文聚焦如何通过 Kafka + Flink + Spark 构建一套稳定、可扩展、可插拔的实时数仓体系。覆盖从数据接入、实时清洗、指标计算,到离线补数、数据一致性保障的完整链路设计,结合实践样例提供可复制的落地方法。 🧱 一、架构总览 ┌────────────┐│ 数据源 …...

React19源码系列之渲染阶段performUnitOfWork
在 React 内部实现中,将 render 函数分为两个阶段: 渲染阶段提交阶段 其中渲染阶段可以分为 beginWork 和 completeWork 两个阶段,而提交阶段对应着 commitWork。 在之前的root.render过程中,渲染过程无论是并发模式执行还是同…...
Redis中的事务和原子性
在 Redis 中,事务 和 原子性 是两个关键概念,用于保证多个操作的一致性和可靠性。以下是 Redisson 和 Spring Data Redis 在处理原子性操作时的区别与对比: 1. Redis 的原子性机制 Redis 本身通过以下方式保证原子性: 单线程模型…...
怎样把B站的视频保存到本地
在B站(哔哩哔哩)上,有数不清的优质内容,无论是搞笑视频、学习资料,还是动漫影视,总有一些视频让你想反复观看。但是,遇到没有网络或流量不够用的时候,怎么办?把B站的视频…...
Vue3前后端分离用户信息显示方案
在Vue3前后端分离的项目中,若后端仅返回用户ID,可通过以下步骤显示用户名: 解决方案 获取用户信息API 确保后端提供以下任意一种接口: 批量查询接口:传入多个用户ID,返回对应的用户信息列表 单个查询接口…...

DL00987-基于深度学习YOLOv11的红外鸟类目标检测含完整数据集
提升科研能力,精准识别红外鸟类目标! 完整代码数据集见文末 针对科研人员,尤其是研究生们,是否在鸟类目标检测中遇到过数据不够精准、处理困难等问题?现在,我们为你提供一款基于深度学习YOLOv11的红外鸟类…...

黑马程序员C++2024新版笔记 第4章 函数和结构体
1.结构体的基本应用 结构体struct是一种用户自定义的复合数据类型,可以包含不同类型的成员。例如: struct Studet {string name;int age;string gender; } 结构体的声明定义和使用的基本语法: struct 结构体类型 {成员1类型 成员1名称;成…...

数据仓库,扫描量
有五种通用技术用于限制数据的扫描量,正如图3 - 4所示。第一种技术是扫描那些被打上时戳的数据。当一个应用对记录的最近一次变化或更改打上时戳时,数据仓库扫描就能够很有效地进行,因为日期不相符的数据就接触不到了。然而,目前的…...
Day126 | 灵神 | 二叉树 | 层数最深的叶子结点的和
Day126 | 灵神 | 二叉树 | 层数最深的叶子结点的和 1302.层数最深的叶子结点的和 1302. 层数最深叶子节点的和 - 力扣(LeetCode) 思路: 这道题用层序遍历的思路比较好想,就把每层的都算一下,然后返回最后一层的和就…...
Python实例题:人机对战初体验Python基于Pygame实现四子棋游戏
目录 Python实例题 题目 代码实现 实现原理 游戏逻辑: AI 算法: 界面渲染: 关键代码解析 游戏棋盘渲染 AI 决策算法 胜利条件检查 使用说明 安装依赖: 运行游戏: 游戏操作: 扩展建议 增强…...

Vue3性能优化: 大规模列表渲染解决方案
# Vue3性能优化: 大规模列表渲染解决方案 一、背景与挑战 背景 在大规模应用中,Vue3的列表渲染性能一直是开发者关注的焦点。大规模列表渲染往往会导致卡顿、内存占用过高等问题,影响用户体验和系统整体性能。 挑战 渲染大规模列表时,DOM操作…...
笔记:将一个文件服务器上的文件(一个返回文件数据的url)作为另一个http接口的请求参数
笔记:将一个文件服务器上的文件(一个返回文件数据的url)作为另一个http接口的请求参数 最近有这么个需求,需要往某一个业务的外部接口上传文件信息,但是现在没有现成的文件,只在数据库存了对应的url&#…...

【RocketMQ 生产者和消费者】- 生产者启动源码 - MQClientInstance 定时任务(4)
文章目录 1. 前言2. startScheduledTask 启动定时任务2.1 fetchNameServerAddr 拉取名称服务地址2.2 updateTopicRouteInfoFromNameServer 更新 topic 路由信息2.2.1 topic 路由信息2.2.2 updateTopicRouteInfoFromNameServer 获取 topic2.2.3 updateTopicRouteInfoFromNameSer…...

超全GPT-4o 风格提示词案例,持续更新中,附使用方式
本文汇集了各类4o风格提示词的精选案例,从基础指令到复杂任务,从创意写作到专业领域,为您提供全方位的参考和灵感。我们将持续更新这份案例集,确保您始终能够获取最新、最有效的提示词技巧。 让我们一起探索如何通过精心设计的提…...

Android 自定义SnackBar和下滑取消
如何自定义SnackBar 首先我们得了解SnackBar的布局: 之前我看有一些方案是获取内部的contentLayout,然后做一些处理。但是现在已经行不通了: RestrictTo(LIBRARY_GROUP) public static final class SnackbarLayout extends BaseTransientB…...

Netty学习专栏(三):Netty重要组件详解(Future、ByteBuf、Bootstrap)
文章目录 前言一、Future & Promise:异步编程的救星1.1 传统NIO的问题1.2 Netty的解决方案1.3 代码示例:链式异步操作 二、ByteBuf:重新定义数据缓冲区2.1 传统NIO ByteBuffer的缺陷2.2 Netty ByteBuf的解决方案2.3 代码示例:…...

详解 C# 中基于发布-订阅模式的 Messenger 消息传递机制:Messenger.Default.Send/Register
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开…...

多场景游戏AI新突破!Divide-Fuse-Conquer如何激发大模型“顿悟时刻“?
多场景游戏AI新突破!Divide-Fuse-Conquer如何激发大模型"顿悟时刻"? 大语言模型在强化学习中偶现的"顿悟时刻"引人关注,但多场景游戏中训练不稳定、泛化能力差等问题亟待解决。Divide-Fuse-Conquer方法,通过…...

Java 函数式接口(Functional Interface)
一、理论说明 1. 函数式接口的定义 Java 函数式接口是一种特殊的接口,它只包含一个抽象方法(Single Abstract Method, SAM),但可以包含多个默认方法或静态方法。函数式接口是 Java 8 引入 Lambda 表达式的基础,通过函…...

分布式锁总结
文章目录 分布式锁什么是分布式锁?分布式锁的实现方式基于数据库(mysql)实现基于缓存(redis)多实例并发访问问题演示项目代码(使用redis)配置nginx.confjmeter压测复现问题并发是1,即不产生并发问题并发30测试,产生并发问题(虽然单实例是synchronized&am…...

使用MybatisPlus实现sql日志打印优化
背景: 在排查无忧行后台服务日志时,一个请求可能会包含多个执行的sql,经常会遇到SQL语句与对应参数不连续显示,或者参数较多需要逐个匹配的情况。这种情况下,如果需要还原完整SQL语句就会比较耗时。因此,我…...
springboot中redis的事务的研究
redis的事务类似于队列操作,执行过程分为三步: 开启事务入队操作执行事务 使用到的几个命令如下: 命令说明multi开启一个事务exec事务提交discard事务回滚watch监听key(s):当监听一个key(s)时,如果在本次事务提交之…...
为什么我输入对了密码,还是不能用 su 切换到 root?
“为什么我输入对了密码,还是不能用 su 切换到 root?” 其实这背后可能不是“密码错了”,而是系统不允许你用 su 切 root,即使密码对了。 👇 以下是最常见的几个真正原因: ❌ 1. Root 用户没有设置密码&…...

client.chat.completions.create方法参数详解
response client.chat.completions.create(model"gpt-3.5-turbo", # 必需参数messages[], # 必需参数temperature1.0, # 可选参数max_tokensNone, # 可选参数top_p1.0, # 可选参数frequency_penalty0.0, # 可选参数presenc…...