百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

MySQL主动报错方法及实践应用调度依赖

yuyutoo 2025-05-08 22:04 3 浏览 0 评论

摘要: MySQL主动报错方法及实践应用调度依赖

关键词: MySQL、主动报错、调度依赖、数据库函数

整体说明

在使用 Dolphinscheduler 的时候,对接三方数据时,对方的数据完成时间不确定,需要找个简单的方法去堵塞任务,整理了一下解决思路,大致如下:

一、问题背景

1.1、对接三方数据

作为数据仓库建设方,需要对接三方数据,并不是我们自己的数据,没法天然的形成数据依赖

1.2、使用 Dolphinscheduler 平台

数据调度使用的是 Dolphinscheduler ,可以配置调度任务,数据集成使用的是 Datax ,用来集成三方数据

1.3、没有部署 Spark

由于项目是个小项目,没有部署大数据能力平台,也没有部署单节点的 Spark ,所以没法使用 Dolphinscheduler 的数据质量任务,

数据质量任务,有天然的表行数校验(复杂的用自定义 SQL)和对应的失败策略堵塞配置,此次没法使用,有兴趣的,可以研究下

1.4、存储数据库 MySQL

小项目存储数据,使用的是 MySQL,后续的主动报错也是基于 MySQL 写的

1.5、上游数据完成时间不是固定时间

由于对接的三方数据,也就是上游数据,并不是 OLTP 的业务系统,数据实时更新,而是一个分析系统,然后数据的生成时间随着机器的内存、CPU、或者他的数据依赖延迟而延迟,每天都不会是固定时间完成, 所以必须设置依赖,否则我们的数据生成任务,就会和源头数据错位,而导致不准确

1.6、有完成时间标记表

上游数据有不确定完成时间问题,所以他们也提供了数据完成的时间

具体表结构如下

CREATE TABLE `table_update_info` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `table_name` varchar(255) DEFAULT NULL COMMENT '表名称',
  `anal_date` varchar(32) DEFAULT NULL COMMENT '计算日期',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间'
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='更新信息表';

当他们昨日数据表计算完成时,就会向这个表插入一条数据

INSERT INTO `table_update_info` (`table_name`, `calc_date`) VALUES ( 'comp_table_name', '2025-04-14');

1.7、尽量简单,不开发

由于项目成本比较低,尽量不通过开发代码的方式去解决问题

二、问题分析

2.1、存在前置查询条件,可以依赖

由于上游给出了完成时间标记的表,那么我们可以通过查询来判断数据是否更新,

限定表名和计算日期为今天,通过是否有数据,来确定是否这个表已经更新

伪代码如下:

select table_name
     from table_update_info
     where table_name = '${完成结果表名}'
     and calc_date = '${昨日时间}') 

如果查询有数据,说明数据已更新,我们可以集成数据了

2.2、调度平台能够报错重试

前面已经确定了,通过 SQL 查询的方式,来判断数据是否已更新,

那就还剩一个问题,如果上游数据不更新,我们需要失败重试,

调度平台,是有这个功能的,截图如下:

三、解决方案

前面的解决方案,看似已经完美了,但是就是有一个问题!

SQL 查询 怎么才能在查不到数据的时候,报错!!!

3.1、尝试1:使用分母为 0方式报错

我们知道 MySQL 数据库,有个报错

ERROR 1365 (22012): Division by 0

这个报错是我最先想到的,当分母为 0 时 会报错

事实上,非常不幸,执行下面语句,并不会报错,只会返回 NULL,且会报一个 warning

select 1/0;

通过 语句查看得知,正是我们要的报错,但是他不是报错,而是 warning,并不能配合前面的报错重试

show WARNINGS;

然后就是去查询为什么不报错呢?

DeepSeek 大模型告诉我,是因为数据库的模式设置的不对,于是我查询数据库是不是严格模式,

可以看到返回的结果,是严格的模式

SELECT @@sql_mode;

这时候我就去,翻阅官方文档,发现,这个模式并不是适合所有语句,只适用于 INSERT 和 UPDATE

于是验证一下,发现确实报错了

CREATE TABLE test (x DECIMAL(5,2));
INSERT INTO test VALUES (1/0);

但是我要的查询的结果,不是插入。而且还要再新建一个表来插入,

结果:未采用!

3.2、尝试2:使用不存在字段方式报错

之后我又问了大模型,他给我这个方式,用不存在的字段,来主动报错

就是 举个例子,当条件是 0 时,不满足我们的条件,我们就查询一个没有字段 比如 invalid_column 来报错,

看起来貌似可以,但是!

无论,0 还是 1,都活报错,应该是 判断字段是否存在的顺利,在 case when 这样的判断之前,所以怎么都会报错

SELECT
    CASE
        WHEN 0 THEN (SELECT invalid_column FROM test)
        ELSE 1
    END AS result;

结果:未采用!

3.3、尝试3:使用 MySQL 函数主动报错

这次我不问大模型了,很多时候,DeepSeek 也不能解决我的问题,甚至回答的结果也是只言片语

这次我百度!

然后我找到了一个方案: 通过创建函数来主动报错,

函数如下:

DELIMITER $
CREATE FUNCTION ThrowIfNull(input_value VARCHAR(255))
RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
    IF input_value IS NULL THEN
        SIGNAL SQLSTATE '45000' 
        SET MESSAGE_TEXT = 'Result is NULL!';
    END IF;
    RETURN input_value;
END$
DELIMITER ;

这个函数很简单,直接能在 MySQL 中执行,逻辑也简单

输入值是 NULL 时,报错!

测试 ,得到我们想要的结果,报错了!

select ThrowIfNull(NULL);

四、最终解决

4.1、解决方式

使用上面的尝试 3 ,配合报错重试解决

SELECT ThrowIfNull(
    (select table_name
     from table_update_info
     where table_name = 'comp_table_name'  -- 表名
     and anal_date = '$[last_day(yyyy-MM-dd)]'  -- 昨天
) AS result

实际配置如下:

4.2、举一反三

  • 对接数据依赖方案
  • 这个方案可以作为数据对接调度依赖方案,简单实用
  • 多调度平台依赖方案
  • 拓展开来,多个平台,比如 Dolphinscheduler 如果不是唯一的调度平台,就像我,还有公司自研的调度平台,两个平台怎么互相依赖,
  • 就可以采用读取平台后台表的方式,来解决

相关推荐

MySQL中的数据类型(mysql数据类型有哪些,并举例)

MySQL中的数据类型...

mysql窗口函数over中rows_MySQL窗口函数

下面的讲解将基于这个employee2表:mysql>SELECT*FROMemployee2;+----+-----------+------+---------+---------...

别再说你精通数据库,MySQL的设计和列类型选取真的很有讲究

总想写一篇MySQL的设计和列类型选取的文章,一直挤不出时间。天天晚上都要加班,正逢5.1放假,抽了几天就有了此文。如果对朋友们能有帮助的话,关注一波不过分吧?求关!选择更优的数据类型尽量选择存储空间...

MySQL数据库知识(mysql数据库相关知识)

MySQL是一种关系型数据库管理系统;那废话不多说,直接上自己以前学习整理文档:查看数据库命令:(1).查看存储过程状态:showprocedurestatus;(2).显示系统变量:show...

数据库:MySQL 高性能优化规范建议

数据库命令规范所有数据库对象名称必须使用小写字母并用下划线分割所有数据库对象名称禁止使用MySQL保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来)数据库对象的命名要能做到见名识意,...

MySQL实战——表结构设计之数字类型

整型不建议刻意去用unsigned属性,因为在做一些数据分析时,SQL可能返回的结果并不是想要得到的结果。比如在财务的场景下,经常会做一些加减操作。MySQL要求unsigned数值相减之...

MySQL数据库入门(四)数据类型简介

在MySQL中数据类型有以下五种:数字整数:常用的有2种,一是int型,int型最多可以表示10位数字(无符号的4开头,有符号的2开头;二是tinyintunsigned,用来表示年龄(值范围是0-...

mysql常用语句超级详细汇总(mysql常用语法)

1.连接数据库:连接本地数据库:mysql-uroot-p连接远程数据库:mysql-h192.169.22.199-uroot-p退出数据库:exit...

MYSQL——CAST()函数的用法(mysql中case)

语法为:Cast(字段名as转换的类型),其中类型可以为:CHAR[(N)]字符型DATE日期型DATETIME日期和时间型...

MySQL存储引擎背后的真相:为何InnoDB并非所有场景的最佳选择

MySQL存储引擎背后的真相:为何InnoDB并非所有场景的最佳选择引言部分你是否遇到过这样的情况:明明已经按照最佳实践选择了MySQL的InnoDB引擎,却发现某些查询依然缓慢得令人沮丧?或者当你的...

MySQL 表分区?涨知识了(mysql数据表分区)

1.什么是表分区...

《MySQL必知必会》_笔记08(mysql必知必会mobi)

第19章插入数据一、数据插入概述INSERT语句用于向数据库表中插入(添加)数据,是SQL中常用的数据操作语句之一。它可以用多种方式使用,包括插入完整的行、插入行的一部分、插入多行以及插入某些查询的...

当 SQL Server(mssql-jdbc) 遇上 BigDecimal → 精度丢失,真坑!

开心一刻  中午和哥们一起喝茶  哥们说道:晚上喝酒去啊...

MYSQL有哪些数据类型(mysql有哪些数据类型,有哪些运算符)

整理下以便查阅,还想吐槽下:这头条怎么就不能给文章分类呢?整数类型...

使用MySQL分区的注意事项(使用mysql分区的注意事项有哪些)

MySQL分区是将一个表分解成多个区块进行操作和保存,从而降低每次操作的数据量,提高性能。从逻辑上看,只有一个表,但物理上这个表可能由多个物理分区组成,每个分区都是一个独立的对象,可以进行独立处理。...

取消回复欢迎 发表评论: