详解如何校验MySQL及Oracle时间字段合规性

 更新时间:2023年06月27日 10:45:42   作者:爱可生云数据库  
这篇文章主要为大家介绍了如何校验MySQL及Oracle时间字段合规性详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

背景信息

在数据迁移或者数据库低版本升级到高版本过程中,经常会遇到一些由于低版本数据库参数设置过于宽松,导致插入的时间数据不符合规范的情况而触发报错,每次报错再发现处理起来较为麻烦,是否有提前发现这类不规范数据的方法,以下基于 Oracle 和 MySQL 各提供一种可行性方案作为参考。

Oracle 时间数据校验方法

创建测试表并插⼊测试数据

CREATE TABLE T1(ID NUMBER,CREATE_DATE VARCHAR2(20));
INSERT INTO T1 SELECT 1, '2007-01-01' FROM DUAL;
INSERT INTO T1 SELECT 2, '2007-99-01' FROM DUAL;            -- 异常数据
INSERT INTO T1 SELECT 3, '2007-12-31' FROM DUAL;
INSERT INTO T1 SELECT 4, '2007-12-99' FROM DUAL;            -- 异常数据
INSERT INTO T1 SELECT 5, '2005-12-29 03:-1:119' FROM DUAL;  -- 异常数据
INSERT INTO T1 SELECT 6, '2015-12-29 00:-1:49' FROM DUAL;   -- 异常数据

创建对该表的错误日志记录

  • Oracle 可以调用 DBMS_ERRLOG.CREATE_ERROR_LOG 包对 SQL 的错误进行记录,用来记录下异常数据的情况,十分好用。
  • 参数含义如下

    • T1 为表名
    • T1_ERROR 为对该表操作的错误记录临时表
    • DEMO 为该表的所属用户
EXEC DBMS_ERRLOG.CREATE_ERROR_LOG('T1','T1_ERROR','DEMO');

创建并插入数据到临时表,验证时间数据有效性

-- 创建临时表做数据校验
CREATE TABLE T1_TMP(ID NUMBER,CREATE_DATE DATE);
-- 插入数据到临时表验证时间数据有效性(增加LOG ERRORS将错误信息输出到错误日志表)
INSERT INTO T1_TMP 
SELECT ID, TO_DATE(CREATE_DATE, 'YYYY-MM-DD HH24:MI:SS')
FROM T1 
LOG ERRORS INTO T1_ERROR REJECT LIMIT UNLIMITED;

校验错误记录

SELECT * FROM DEMO.T1_ERROR;

其中 ID 列为该表的主键,可用来快速定位异常数据行。

MySQL 数据库的方法

创建测试表模拟低版本不规范数据

-- 创建测试表
SQL> CREATE TABLE T_ORDER(
    ID BIGINT AUTO_INCREMENT PRIMARY KEY,
    ORDER_NAME VARCHAR(64),
    ORDER_TIME DATETIME);
-- 设置不严谨的SQL_MODE允许插入不规范的时间数据
SQL> SET SQL_MODE='STRICT_TRANS_TABLES,ALLOW_INVALID_DATES';
SQL> INSERT INTO T_ORDER(ORDER_NAME,ORDER_TIME) VALUES 
        ('MySQL','2022-01-01'),
        ('Oracle','2022-02-30'),
        ('Redis','9999-00-04'),
        ('MongoDB','0000-03-00');
-- 数据示例
SQL> SELECT * FROM T_ORDER;
+----+------------+---------------------+
| ID | ORDER_NAME | ORDER_TIME          |
+----+------------+---------------------+
|  1 | MySQL      | 2022-01-01 00:00:00 |
|  2 | Oracle     | 2022-02-30 00:00:00 |
|  3 | Redis      | 9999-00-04 00:00:00 |
|  4 | MongoDB    | 0000-03-00 00:00:00 |
+----+------------+---------------------+

创建临时表进行数据规范性验证

-- 创建临时表,只包含主键ID和需要校验的时间字段
SQL> CREATE TABLE T_ORDER_CHECK(
    ID BIGINT AUTO_INCREMENT PRIMARY KEY,
    ORDER_TIME DATETIME);
-- 设置SQL_MODE为5.7或8.0高版本默认值
SQL> SET SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
-- 使用INSERT IGNORE语法插入数据到临时CHECK表,忽略插入过程中的错误
SQL> INSERT IGNORE INTO T_ORDER_CHECK(ID,ORDER_TIME) SELECT ID,ORDER_TIME FROM T_ORDER;

数据比对

将临时表与正式表做关联查询,比对出不一致的数据即可。

SQL> SELECT 
    T.ID,
    T.ORDER_TIME AS ORDER_TIME,
    TC.ORDER_TIME AS ORDER_TIME_TMP
FROM T_ORDER T INNER JOIN T_ORDER_CHECK TC 
ON T.ID=TC.ID
WHERE T.ORDER_TIME<>TC.ORDER_TIME;
+----+---------------------+---------------------+
| ID | ORDER_TIME          | ORDER_TIME_TMP      |
+----+---------------------+---------------------+
|  2 | 2022-02-30 00:00:00 | 0000-00-00 00:00:00 |
|  3 | 9999-00-04 00:00:00 | 0000-00-00 00:00:00 |
|  4 | 0000-03-00 00:00:00 | 0000-00-00 00:00:00 |
+----+---------------------+---------------------+

一个取巧的小方法

对时间字段用正则表达式匹配,对有严谨性要求的情况还是得用以上方式,正则匹配烧脑。

-- Oracle 数据库
SELECT * FROM  T1 WHERE NOT REGEXP_LIKE(CREATE_DATE,'^((?:19|20)\d\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$');
    ID CREATE_DATE
---------- --------------------
     2 2007-99-01
     4 2007-12-99
     5 2005-12-29 03:-1:119
     6 2015-12-29 00:-1:49
-- MySQL 数据库
-- 略,匹配规则还在调试中

关于 SQLE

爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。

SQLE 获取

类型地址
版本库https://github.com/actiontech/sqle
文档https://actiontech.github.io/sqle-docs/
发布信息https://github.com/actiontech/sqle/releases
数据审核插件开发文档https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_audit...

以上就是详解如何校验MySQL及Oracle时间字段合规性的详细内容,更多关于MySQL Oracle时间字段合规性的资料请关注脚本之家其它相关文章!

相关文章

  • MySQL数据库查询性能优化策略

    MySQL数据库查询性能优化策略

    这篇文章主要介绍了MySQL数据库查询性能优化的策略,帮助大家的工作学习提高MySQL数据库的性能,感兴趣的朋友可以了解下
    2020-08-08
  • Mysql中的常用调优参数用法及解读

    Mysql中的常用调优参数用法及解读

    文章介绍了MySQL数据库的一些关键配置参数,包括InnoDB缓冲池、redolog缓冲区、日志缓冲区等,并解释了这些参数在数据库性能和事务一致性中的作用,文章通过比喻和实际建议帮助读者理解这些配置参数的合理设置
    2025-12-12
  • MySQL数据库怎么正确查询字符串长度

    MySQL数据库怎么正确查询字符串长度

    MySQL中字符串长度一般指数据库表中一个字段或列中存储的字符串的最大长度,有时我们需要测量字符串长度,来保证表结构及数据库性能稳定,下面这篇文章主要给大家介绍了关于MySQL数据库怎么正确查询字符串长度的相关资料,需要的朋友可以参考下
    2023-06-06
  • MySQL详细讲解多表关联查询

    MySQL详细讲解多表关联查询

    在数据库的设计中, 我们通常都是会有很多张表 , 通过表与表之间的关系建立我们想要的数据关系, 所以在多张表的前提下, 多表的关联查询就尤为重要
    2022-04-04
  • MySQL表的增删查改操作实例代码

    MySQL表的增删查改操作实例代码

    MySQL表的增删查改(CRUD)是数据库中非常基础的部分,也是后端开发日常工作中,最重要的一项工作,这篇文章主要介绍了MySQL表的增删查改操作的相关资料,需要的朋友可以参考下
    2025-07-07
  • 数据库类型转换导致SQL不走索引的案例

    数据库类型转换导致SQL不走索引的案例

    在SQL中数据类型转换是基础且关键的操作,分为隐式和显式转换,隐式转换由系统自动完成,虽便捷但可能带来性能损耗、索引失效及数据准确性风险,这篇文章主要介绍了数据库类型转换导致SQL不走索引的案例,需要的朋友可以参考下
    2026-05-05
  • Mysql查询日期timestamp格式的数据实现

    Mysql查询日期timestamp格式的数据实现

    本文主要介绍了Mysql查询日期timestamp格式的数据实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • 一文说透什么是MySQL的预编译

    一文说透什么是MySQL的预编译

    这篇文章主要介绍了一文说透什么是MySQL的预编译,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • MySQL扩展VARCHAR长度遭遇问题汇总分析

    MySQL扩展VARCHAR长度遭遇问题汇总分析

    这篇文章主要为大家介绍了MySQL扩展VARCHAR长度遭遇问题汇总分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-02-02
  • MYSQL数据库中cmd命令操作详解

    MYSQL数据库中cmd命令操作详解

    今天我们就来看一下数据库的各种命令,以下命令全部是从CMD命令窗口下的命令行输入指令,首先如果如果输入mysql,系统提示“mysql不是内部命 令或外部命令
    2016-04-04

最新评论