一文掌握如何编写可重复执行的SQL
一文掌握如何编写可重复执行的SQL
文章已同步个人博客:一文掌握如何编写可重复执行的SQL
背景
先提出问题,这里的可重复执行是指什么?我们为什么要编写可重复执行的sql?
可重复执行是指一条sql重复多次执行都不会报错,不会因为报错而中断同sql脚本的其它sql语句。
比如如下的建表sql只能执行一次,再次执行就会报错,提示我们example_table
表已存在。
CREATE TABLE `example_table` (`id` INT NOT NULL AUTO_INCREMENT,`name` VARCHAR(100) NOT NULL,`age` INT DEFAULT 0,`email` VARCHAR(200),PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
通常来说项目发版的执行SQL脚本语句是由DDL 和 DML 组成的,如果SQL脚本文件中某个SQL执行异常就会中断整个SQL脚本文件的执行。我们还要根据报错SQL的位置,重新将SQL脚本文件中未执行的SQL摘出来重新整理执行。一旦报错,整个SQL脚本执行过程就变得繁琐起来。
编写可重复执行的SQL,变成了解决这一痛点的利器。当SQL脚本中的SQL语句都是可重复执行的,脚本中某个SQL有问题,直接在当前SQL脚本中就可以修改,我们若需要重新执行,只需要重新执行该SQL脚本就可以。其他已经执行成功的SQL,依然会成功执行,也不会对库表数据造成影响。接下来我们梳理一下各类SQL可重复执行的写法和注意点,本文中的SQL均基于MySql语法。
如何实现
表格列举出编写SQL中常见的sql需求:
SQL | SQL类型 |
---|---|
创建表 | DDL |
对表新增字段 | DDL |
对表修改字段 | DDL |
对表新增索引 | DDL |
插入一条新记录 | DML |
对表中记录进行更新 | DML |
对表中记录进行删除 | DML |
编写SQL涉及到的Mysql语法和系统表
IF NOT EXISTS
- MySql 预处理语句原生语法
- 字段表
INFORMATION_SCHEMA.COLUMNS
- 索引表
INFORMATION_SCHEMA.STATISTICS
- 查询当前数据库名称
SCHEMA()
预处理语句语法介绍
预处理语句(Prepared Statements)是一种将 SQL 查询与其参数分离的机制。与传统的查询方式不同,预处理语句首先会将 SQL 查询进行编译、优化,并将其缓存,随后可以多次执行该查询,而不必每次都重新编译和解析 SQL 语句。每次执行时,预处理语句只需要提供不同的参数即可,这使得它在需要执行多次相同 SQL 查询的场景中具有明显的性能优势。
-- 准备预处理语句
PREPARE stmt FROM 'SELECT name, age FROM users WHERE id = ?';-- 设置参数并执行语句
SET @userId = 1;
EXECUTE stmt USING @userId;-- 释放预处理语句
DEALLOCATE PREPARE stmt;
PREPARE
将带有占位符?
的 SQL 语句预处理并编译。SET
用于设置查询参数。EXECUTE
执行预处理语句并传递参数。DEALLOCATE PREPARE
释放预处理语句,避免占用资源。
接下来具体说明一下各种sql如何改写为可重复执行的写法。
创建表
原写法:
CREATE TABLE `example_table` (`id` INT NOT NULL AUTO_INCREMENT,`name` VARCHAR(100) NOT NULL,`age` INT DEFAULT 0,`email` VARCHAR(200),PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
创建表可以使用IF NOT EXISTS
语法进行判断,仅当表不存在的时候才会创建表。
可重复执行的写法:
CREATE TABLE IF NOT EXISTS `example_table` (`id` INT NOT NULL AUTO_INCREMENT,`name` VARCHAR(100) NOT NULL,`age` INT DEFAULT 0,`email` VARCHAR(200),PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
对表新增字段
原写法:
ALTER TABLE example_table ADD COLUMN create_time datetime null comment '创建时间';
我们能不能也判断如果这个表中没有这个字段才执行新增字段,答案是可以的。在这里就要用到 MySql 预处理语句的语法了。
判断,如果在当前数据库中,存在当前这个表,表中没有这个字段,那么才会执行新增该字段。
INFORMATION_SCHEMA.COLUMNS
系统级的字段表,记录了全部的字段信息SCHEMA()
当前数据库名称
可重复执行的写法:
set @sql = 'select 1 from dual;';
select ' ALTER TABLE example_table add COLUMN create_time datetime NULL comment ''创建时间'' ;' into @sql
from dual where (select count(1) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='example_table' AND COLUMN_NAME='sort')=0;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
对表修改字段
原写法:
ALTER TABLE example_table MODIFY COLUMN email VARCHAR(500) DEFAULT '' comment '邮箱';
同样使用 MySql 预处理语句的语法,判断在当前数据库中,存在这个表,且有这个字段,那么才会执行修改字段的语句。
可重复执行的写法:
set @sql = 'select 1 from dual;';
select ' ALTER TABLE example_table MODIFY COLUMN email VARCHAR(500) DEFAULT '''' comment ''邮箱'' ;' into @sql
from dual where (select count(1) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='example_table' AND COLUMN_NAME='email')=1;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
对表新增索引
原写法:
ALTER TABLE example_table add index idx_name (name) COMMENT '名称索引';
要判断当前数据库中,这个表中,根据索引名查询,未查到该索引就进行添加索引。
INFORMATION_SCHEMA.STATISTICS
系统级的索引表,记录了全部的索引信息
可重复执行的写法:
set @sql = 'select 1 from dual;';
select 'ALTER TABLE example_table add index idx_name (name) COMMENT ''名称索引'';' into @sql from dual
where (select count(1) FROM INFORMATION_SCHEMA.STATISTICS where TABLE_SCHEMA=SCHEMA() and TABLE_NAME='example_table' and index_name='idx_name')=0;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
插入一条新记录
原写法:
insert into example_table(name, age, email, create_time) VALUE ('jack', 18, 'jackaaa@gmail.com', now());
在这里我们判断如果这个表中没有jack这个name,才进行插入记录。使用DUAL虚拟表帮助我们添加判断条件。
可重复执行的写法:
INSERT INTO example_table
(name, age, email, create_time)
SELECT 'jack', 18, 'jackaaa@gmail.com', now()
FROM DUAL
WHERE NOT EXISTS (select id from example_table where name = 'jack');
对表中记录进行更新
update
语句因为其天生的幂等特质,不需要改写,就支持可重复执行。
update example_table set age = 20 where name = 'jack';
对表中记录进行删除
delete
语句因为其天生的幂等特质,不需要改写,就支持可重复执行。
delete from example_table where name = 'tom';
总结
至此,SQL脚本中常见的7类SQL写法如何改写为可重复执行的SQL,就整理完成了。可重复执行的SQL脚本不仅在执行时提供了便利,也为项目迁移,项目本地化部署带来了便利。
参考
- mysql性能优化-预处理语句(Prepared Statements)
相关文章:
一文掌握如何编写可重复执行的SQL
一文掌握如何编写可重复执行的SQL 文章已同步个人博客:一文掌握如何编写可重复执行的SQL 背景 先提出问题,这里的可重复执行是指什么?我们为什么要编写可重复执行的sql? 可重复执行是指一条sql重复多次执行都不会报错…...
编译笔记:vs 中 正在从以下位置***加载符号 C# 中捕获C/C++抛出的异常
加载符号 解决方法: 进入VS—工具—选项----调试----符号,看右边有个“Microsoft符号服务器”,将前面的勾去掉,(可能还有删除下面的那个缓存)。 参考 C# 中捕获C/C抛出的异常 在需要捕捉破坏性异常的函数…...
[搜广推]王树森推荐系统——Deep Retrieval 召回
Deep Retrieval 简介 Deep Retrieval 是一种推荐系统框架,它将物品表示为路径(path),并在线上查找与用户最匹配的路径。 这种方法与传统的双塔模型不同,后者通常将用户和物品表示为向量,并在线上进行最近邻…...
【深入解析蓝牙dumpsys bluetooth_manager 命令输出】
了解蓝牙的工作状态以及如何在测试中利用这些信息。 1. Bluetooth Status(蓝牙状态) enabled: true state: ON address: 00:00:00:00:43:36 name: 小米手机 time since enabled: 00:15:18.492enabled: true — 蓝牙功能已启用。state: ON — 蓝牙目前是开启状态。address: …...
【三】Fast-DDS hello world!
编译hello world # 进入到源码目录 mkdir -p examples/cpp/hello_world/build cd examples/cpp/hello_world/build cmake .. && make -j4运行publisher ./hello_world publisher 运行subscriber ./hello_world subscriber 结果...
将HTML转换为PDF:使用Spire.Doc的详细指南(一) 试用版
目录 引言 1. 为什么选择 Spire.Doc? 1.1 主要特点 1.2 适用场景 2. 准备工作 2.1 引入 Spire.Doc 依赖 2.2 禁用 SSL 证书验证 3. 实现功能 3.1 主类结构 3.2 代码解析 4. 处理图像 5. 性能优化 5.1 异步下载图像 示例代码 5.2 批量处理优化 示例代…...
【物联网技术与应用】实验10:蜂鸣器实验
实验10 蜂鸣器实验 【实验介绍】 蜂鸣器是音频信号装置。蜂鸣器可分为有源蜂鸣器和无源蜂鸣器。 【实验组件】 ● Arduino Uno主板* 1 ● USB数据线* 1 ● 有源蜂鸣器* 1 ● 无源蜂鸣器* 1 ● 面包板* 1 ● 9V方型电池* 1 ● 跳线若干 【实验原理】 如图所示&#x…...
【python高级】342-TCP服务器开发流程
CS模式:客户端-服务端模式 TCP客户端开发流程介绍(五步)(C端) 1.创建客户端套接字对象 2.和服务端套接字建立连接 3.发送数据 4.接收数据 5.关闭客户端套接字 TCP服务端开发流程(七步)…...
C++开源项目 VLC 源代码的交叉编译以及库的裁剪方法详解
目录 1、VLC简介 2、VLC编译环境配置 2.1、编译环境 2.2、编译环境配置 2.2.1、下载安装MSYS2 2.2.2、下载mingw-w64 3、编译VLC 4、VLC库的裁剪 5、总结 C软件异常排查从入门到精通系列教程(核心精品专栏,订阅量已达600多个,欢迎订…...
draw.io 导出svg图片插入word后模糊(不清晰 )的解决办法
通常我们将图片从draw.io导出为svg格式后插入word, 会发现字体不清晰,特别是使用宋体时,折腾了半天,得到如下办法: 方法1: 在draw.io中导出pdf文件,使用 PDF转SVG转换器 - SVGConverter 将其转换为svg, 完美呈现。 …...
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
目录 详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用 一、什么是柯里化? 1、原理解析 2、一个直观的例子 二、如何实现柯里化? 1、底层实现 2、工作原理解析 3…...
Cesium材质——Material
简介: Cesium.Material对象的目的,就是生成一段名称为czm_getMaterial的函数(示例代码如下), 这个czm_getMaterial函数,是shader代码,会被放到片元着色器中使用。 czm_material czm_getMater…...
《点点之歌》“意外”诞生记
世界是“点点”的,“点点”是世界的。 (笔记模板由python脚本于2024年12月23日 19:28:25创建,本篇笔记适合喜欢诗文的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 …...
统计某个文件中某个字符串出现的次数
要统计某个文件中某个字符串出现的次数,有多种方法可以实现。以下是几种常用且高效的 Linux 命令方法: 方法一:使用 grep 和 wc 命令示例: grep -o "字符串" 文件名 | wc -l说明: grep -o "字符串&…...
C++简明教程(文章要求学过一点C语言)(3)
一、编程工具大揭秘——IDE 当我们准备踏入 C 编程的奇妙世界时,首先要认识一个重要的“魔法盒子”——集成开发环境(IDE)。IDE 就像是一个全能的编程工作室,它把我们写代码所需要的各种工具都整合到了一起,让编程这件…...
Springboot高并发乐观锁
Spring Boot分布式锁的主要缺点包括但不限于以下几点: 性能开销:使用分布式锁通常涉及到网络通信,这会引入额外的延迟和性能开销。例如,当使用Redis或Zookeeper实现分布式锁时,每次获取或释放锁都需要与这些服务进行交…...
编译原理复习---正则表达式+有穷自动机
适用于电子科技大学编译原理期末考试复习。 1. 正则表达式 正则表达式(Regular Expression,简称regex或regexp)是一种用于描述、匹配和操作文本模式的强大工具。它由一系列字符和特殊符号组成,这些字符和符号定义了一种搜索模式…...
如何使用ChatGPT辅助文献综述,以及如何进行优化?一篇说清楚
目录 1.写在开头 2.ChatGPT 3.提示词研究 4.第一轮研究 5.第二轮研究 6.生成文献综述 嘿宝子们!今天我们要聊的,可是个让学术圈都为之振奋的话题——ChatGPT辅助文献综述。这个教育界的新宠儿,已经不满足于仅仅在学习和教学中露两手了&…...
ZZNUOJ 1601:字母序号(C/C++/Java)
题目描述 我们把字母 A-Z 分别编号为 1-26, 现在给你一个大写字母, 输出这个大写字母的序号。 输入 输入一个大写字母 输出 输出这个大写字母的序号 样例输入 C 样例输出 3 常见的ASCII值 ASCII表中可以记下部分特殊的值(十进制)(字母从A到Z,从a到z,ASCII值依次递增)...
[CISCN 2021初赛]rsa
[CISCN 2021初赛]rsa 源代码: from flag import text,flag import md5 from Crypto.Util.number import long_to_bytes,bytes_to_long,getPrimeassert md5.new(text).hexdigest() flag[6:-1]msg1 text[:xx] msg2 text[xx:yy] msg3 text[yy:]msg1 bytes_to_lo…...
Electron -- Electron Fiddle(一)
Electron Fiddle 是一个由 Electron 团队开发的开源工具,它允许开发者快速创建、运行和调试 Electron 应用。这个工具提供了一个简洁的界面,使用户无需配置复杂的开发环境,就能快速体验和学习 Electron。强烈建议将其安装为学习工具。 学习它…...
java 实现排序的几种方式
冒泡排序(Bubble Sort) 基本原理: 它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 示例代码如下: 登…...
【机器学习与数据挖掘实战】案例06:基于Apriori算法的餐饮企业菜品关联分析
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…...
陀螺仪选型
瑞芬官网 datasheet 陀螺仪、IMU姿态仪、陀螺转角仪、三轴姿态仪、三轴陀螺仪 mid360 imu ICM-40609-D TDK InvenSense | Mouser https://product.tdk.com/system/files/dam/doc/product/sensor/mortion-inertial/imu/data_sheet/ds-000330_icm-40609-d_v1.2.pdf...
【超详细实操内容】django的身份验证系统之限制用户访问的三种方式
目录 1、使用request.user.is_authenticated属性 2、装饰器login_required 3、LoginRequiredMixin类 通常情况下,网站都会对用户限制访问,例如,未登录的用户不可访问用户中心页面。Django框架中使用request.user.isauthenticated属性、装饰器loginrequired和LoginRequire…...
Pika Labs技术浅析(六):自动化技术
Pika Labs 的自动化技术旨在通过工作流引擎和自动化警报系统,帮助用户实现业务流程的自动化和实时监控。 一、自动化技术模块概述 Pika Labs 的自动化技术模块旨在通过以下两个核心组件,实现业务流程的自动化和实时监控: 1.工作流引擎&…...
springboot471基于协同过滤算法商品推荐系统(论文+源码)_kaic
摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装协同过滤算法商品推荐系统软件来发挥其高效地信息处理的作用…...
【YashanDB知识库】jdbc查询st_geometry类型的数据时抛出YAS-00101错误
本文内容来自YashanDB官网,原文内容请见 https://www.yashandb.com/newsinfo/7802956.html?templateId1718516 问题现象 某客户的业务在通过YashanDB jdbc驱动查询含有st_geometry列的数据时,报如下异常:YAS-00101 cannot allocate 0 byte…...
ajax中get和post的区别,datatype返回的数据类型有哪些?web开发中数据提交的几种方式,有什么区别。
在 Web 开发中,GET 和 POST 是两种常见的 HTTP 请求方法,它们有一些显著的区别。此外,datatype 参数在 jQuery 的 ajax() 请求中指定了预期的响应数据类型。接下来,我会详细解释这些问题。 1. GET 和 POST 请求的区别 GET 请求 和…...
EKF异常状态自检
https://wenku.csdn.net/column/25p1jkf4vz https://www.zhihu.com/question/293038308/answers/updated https://zhuanlan.zhihu.com/p/12011086094 常用数据分析方法:方差分析及实现!-腾讯云开发者社区-腾讯云 方差分析的七种类型_双因素方差分析 自变…...
《解析 MXNet 的 C++版本在分布式训练中的机遇与挑战》
在深度学习的广袤领域中,分布式训练已成为应对大规模数据和复杂模型训练需求的关键手段。MXNet 作为一款备受瞩目的深度学习框架,其 C版本在分布式训练方面展现出独特的魅力,同时也面临着诸多挑战。深入探究这些优势与挑战,对于推…...
UVM学习总结
问题1:同时出现几个相同的uvm_config_de()哪个有效? UVM中的配置对象是通过uvm_config_db类实现的。uvm_config_db类使用一对名称和值来存储配置信息。当多个uvm_config_db.call()调用同时提供相同名称的配置时,最后一个调用将覆盖之前的调用…...
TCP/IP 介绍:网络通信的基石
TCP/IP 介绍:网络通信的基石 计算机通信协议概述 在数字时代,计算机之间的通信变得至关重要。计算机通信协议(Computer Communication Protocol)是一套规则,定义了计算机如何相互交流信息。这些协议确保了不同制造商…...
华为IPD流程6大阶段370个流程活动详解_第二阶段:计划阶段 — 86个活动
华为IPD流程涵盖了产品从概念到上市的完整过程,各阶段活动明确且相互衔接。在概念启动阶段,产品经理和项目经理分析可行性,PAC评审后成立PDT。概念阶段则包括产品描述、市场定位、投资期望等内容的确定,同时组建PDT核心组并准备项目环境。团队培训涵盖团队建设、流程、业务…...
基于Spring Boot的建材租赁系统
一、系统背景与目的 随着建筑行业的快速发展,建材租赁需求日益增加。传统的建材租赁管理方式大多依赖于纸质文档或简单的电子表格,不仅效率低下,还容易出现信息遗漏和错误。为了解决这些问题,基于Spring Boot的建材租赁系统应运而…...
YOLO v5 Series - MQTT
MQTT...
uni-app开发订单列表页面
目录 一:功能描述 二:功能实现 一:功能描述 订单列表页面包含三个部分,最上面显示订单的状态信息,可以根据订单进行切换,中间显示订单的商品和价格信息,最下面显示订单的操作按钮,可以根据不同的状态操作订单。 二:功能实现 1:状态切换 <view class="nav-…...
14,攻防世界Web_php_unserialize
进入场景 看见代码,解析一下 这段PHP代码定义了一个名为Demo的类,并演示了如何通过URL参数进行反序列化和文件高亮显示的功能,同时也包含了一些安全措施以防止对象注入攻击。下面是对这段代码的逐行解释: 1.<php 开始PHP代码…...
基于单片机的电梯声控系统设计(论文+源码)
1.系统设计 在目前的高楼住宅,商业大厦中电梯是不可或缺的,而传统的电梯控制器系统,通常需要用户用手去按下按键进行控制,但是这种方式在有些情况下,并不完善,比如在本次新冠疫情期间,由于新冠…...
宠物用品电子商务系统|Java|SSM|VUE| 前后端分离
【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…...
每日一题 341. 扁平化嵌套列表迭代器
341. 扁平化嵌套列表迭代器 展开成数组来解题 class NestedIterator {vector<int> nums;int idx;void flattened(vector<NestedInteger> &nestedList){for(int i0;i<nestedList.size();i){if(nestedList[i].isInteger()){nums.push_back(nestedList[i].get…...
小程序 - 模拟时钟
微信小程序常用API练习 - 模拟时钟小程序开发笔记 模拟时钟 “模拟时钟”微信小程序是一个简约风格的动态时钟,该时钟时间与系统时间一致,且时针、分针、秒针会与系统时间同步更新,用户可以很方便地查看时间。下面将对“模拟时钟”微信小程序…...
UDP的报文结构和特点
1.UDP传输协议的特点 使用UDP传输协议进行通信,过程类似于寄信,它的特点如下: 无连接:知道对端的IP号和端口号就直接进行传输,不需要建立连接;不可靠:没有可靠机制,发送数据包以后&a…...
如何在服务器上克隆、pull、push GitHub私有项目
诸神缄默不语-个人CSDN博文目录 情况是这样的,我直接用git clone命令后,会提示让我输入GitHub账号密码,我输入后它还是显示克隆失败,并显示: Cloning into folder_name... Username for https://github.com: user_na…...
mybatis 动态 SQL
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底…...
LeetCode 1661. 每台机器的进程平均运行时间
LeetCode 1661. 每台机器的进程平均运行时间 表: Activity ----------------------- | Column Name | Type | ----------------------- | machine_id | int | | process_id | int | | activity_type | enum | | timestamp | float | ----------------------- 该表展示了一家工厂…...
【RabbitMQ】RabbitMQ保证消息不丢失的N种策略的思想总结
文章目录 生产者端(消息发布端)保证机制RabbitMQ服务器端保证机制消费者端(消息接收端)保证机制除了MQ自带的机制,还能做的操作持久化的原理ACK思想 更多相关内容可查看 消息从发送,到消费者接收࿰…...
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
人无完人,持之以恒,方能见真我!!! 共同进步!! 文章目录 一、翻译环境和运行环境二、翻译环境1.编译预处理编译汇编 2.链接 三、运行环境 一、翻译环境和运行环境 在 ANSI C 的任何⼀种实现中&am…...
Codeforces Round 994 (Div. 2)-D题
题目链接:https://codeforces.com/contest/2049/problem/D 题目大意是在开始移动之前,可以任意次将一行元素向左挪一格,代价是1,开始游戏后,只能向下走或者向右走,直到走到终点,问最小代价是多少. constexpr ll inf 1E18; void solve() {int n, m, K;std::cin >> n &g…...
【计算机视觉】opencv-停车位检测原理及代码演示
概述 本文介绍了一种基于OpenCV库的停车场空位检测方法。通过本项目演示,可以对opencv库有更深刻的理解。文章详细阐述了检测原理、算法流程以及代码实现。 一、原理介绍 基于OpenCV的停车位检测原理涉及多个图像处理步骤,以下将结合相关公式详细介绍每…...