21人参与 • 2026-08-05 • Mysql
文档版本:v2.0
适用场景:mysql 数据库中大量表,需快速定位所有表中 created_date 字段值为 '0000-00-00 00:00:00' 的记录。
提供方式:存储过程(纯 sql 统计) + python 脚本(灵活导出)。
created_date 字段。'0000-00-00 00:00:00'。| 对比维度 | 存储过程(纯 sql) | python 脚本 |
|---|---|---|
| 运行环境 | 仅需 mysql 客户端(命令行、navicat 等) | 需 python 3.6+ 及 pymysql 库 |
| 结果输出 | 返回结果集(表名 + 记录数) | 可导出为 csv 文件,或直接打印示例 |
| 对数据库影响 | 全在数据库内执行,速度更快 | 逐表查询,网络开销稍大 |
| 灵活性 | 逻辑固化,修改需重建存储过程 | 易于修改(如增加分页、并发、过滤条件) |
| 适用场景 | dba 快速巡检、仅需统计数量的场景 | 一次性深度排查、数据导出、定期自动化脚本 |
| 推荐使用 | 仅想快速获知哪些表有问题时 | 需要导出详细记录时 |
建议:先运行存储过程查看统计结果,若有问题表再使用 python 脚本导出详细数据。
该存储过程遍历所有包含 created_date 列的表,统计每张表中零日期记录的数量,并返回汇总结果集。
delimiter $$
drop procedure if exists count_zero_date$$
create procedure count_zero_date()
begin
declare done int default false;
declare tbl_name varchar(255);
-- 游标:获取所有基表(排除视图)中具有 created_date 列的表
declare cur cursor for
select distinct c.table_name
from information_schema.columns c
inner join information_schema.tables t
on c.table_schema = t.table_schema
and c.table_name = t.table_name
where c.table_schema = database()
and c.column_name = 'created_date'
and c.data_type in ('datetime', 'timestamp', 'date')
and t.engine is not null; -- 关键:排除视图
declare continue handler for not found set done = true;
-- 创建内存临时表存储统计结果
drop temporary table if exists tmp_zero_count;
create temporary table tmp_zero_count (
table_name varchar(255) primary key,
zero_count int not null
) engine = memory;
open cur;
read_loop: loop
fetch cur into tbl_name;
if done then
leave read_loop;
end if;
-- 动态统计并插入(仅记录 zero_count > 0 的表)
set @sql = concat(
'insert into tmp_zero_count (table_name, zero_count) ',
'select ''', tbl_name, ''', count(*) ',
'from `', tbl_name, '` ',
'where created_date = ''0000-00-00 00:00:00'' ',
'having count(*) > 0'
);
prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;
end loop;
close cur;
-- 返回最终结果
select * from tmp_zero_count order by zero_count desc;
drop temporary table tmp_zero_count;
end$$
delimiter ;
在数据库中执行上述代码(使用 mysql 客户端或工具如 navicat、dbeaver)。
调用存储过程:
call count_zero_date();
将返回一张两列的结果表:
| table_name | zero_count |
|---|---|
| attendance_config_position | 15 |
| user_log | 3 |
| … | … |
仅列出存在零日期记录的表,按数量降序排列。
created_date 列无索引,全表扫描可能较慢,可考虑在执行前为该列临时建立索引(事后删除)。select * 改为 select table_name 并移除 zero_count 列。python 版本:3.6 及以上。
安装依赖库:
pip3 install pymysql
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pymysql
import sys
import csv
# ==================== 配置区(请按实际修改)====================
db_config = {
'host': 'localhost',
'port': 3306,
'user': 'your_user',
'password': 'your_password',
'database': 'your_database',
'charset': 'utf8mb4'
}
zero_date = '0000-00-00 00:00:00' # 待查找的零日期
output_csv = 'zero_date_records.csv' # 输出文件,设为 none 则只打印不写文件
# =============================================================
def get_tables_with_column(cursor, db_name, column_name):
"""
获取当前数据库中所有包含指定列的基表(排除视图)
使用 engine is not null 判断基表,兼容所有 mysql 版本
"""
sql = """
select c.table_name
from information_schema.columns c
inner join information_schema.tables t
on c.table_schema = t.table_schema
and c.table_name = t.table_name
where c.table_schema = %s
and c.column_name = %s
and c.data_type in ('datetime', 'timestamp', 'date')
and t.engine is not null
"""
cursor.execute(sql, (db_name, column_name))
return [row[0] for row in cursor.fetchall()]
def main():
conn = none
try:
conn = pymysql.connect(**db_config)
cursor = conn.cursor()
db_name = db_config['database']
tables = get_tables_with_column(cursor, db_name, 'created_date')
if not tables:
print("未找到任何包含 'created_date' 列的基表。")
return
print(f"共发现 {len(tables)} 个表含有 created_date 列,开始扫描...")
total_records = 0
result_rows = [] # 存储所有匹配记录(含表名列)
for tbl in tables:
# 使用参数化查询,安全可靠
query = f"select * from `{tbl}` where created_date = %s"
cursor.execute(query, (zero_date,))
rows = cursor.fetchall()
if rows:
# 首次遇到数据时,获取列名构造表头
if not result_rows:
col_names = [desc[0] for desc in cursor.description]
result_rows.append(['table_name'] + col_names)
for row in rows:
result_rows.append([tbl] + list(row))
total_records += len(rows)
print(f"表 {tbl}: 发现 {len(rows)} 条零日期记录")
print(f"\n扫描完成,总计发现 {total_records} 条记录。")
# 输出结果
if output_csv and result_rows:
with open(output_csv, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.writer(f)
writer.writerows(result_rows)
print(f"详细结果已写入文件:{output_csv}")
elif result_rows:
# 不写文件则打印前20条示例
print("\n示例数据(前20条):")
for i, row in enumerate(result_rows[1:21], 1):
print(f"{i}. {row}")
else:
print("未发现任何零日期记录。")
cursor.close()
except pymysql.error as e:
print(f"数据库错误: {e.args[0]} - {e.args[1]}")
sys.exit(1)
except exception as e:
print(f"发生未知错误: {e}")
sys.exit(1)
finally:
if conn:
conn.close()
if __name__ == '__main__':
main()修改脚本开头的 db_config 字典,填入正确的数据库连接信息。
执行命令:
python3 find_zero_date.py
结果将自动写入 zero_date_records.csv(可自定义文件名),包含表名和该表所有列的数据;若设置 output_csv = none,则仅打印前20条示例。
query 末尾添加 limit 1000,避免内存溢出。concurrent.futures 并发查询多张表(注意数据库连接数限制)。select * 改为 select count(*),修改脚本逻辑即可。q1:执行存储过程报错unknown column 'engine' in 'where clause'?
a:您的 mysql 版本过旧(< 5.0),information_schema.tables 中无 engine 列。请升级数据库,或改用 table_type = 'base table'(如果支持)。若均不支持,可去掉 and t.engine is not null 条件,但可能包含视图导致查询失败。
q2:python 脚本报错modulenotfounderror: no module named 'pymysql'?
a:执行 pip3 install pymysql 安装依赖。
q3:零日期条件匹配不到任何数据,但确实存在'0000-00-00 00:00:00'?
a:检查 sql_mode 是否包含 no_zero_date,该模式可能将零日期视为 '0000-00-00'(date 类型)。可尝试将条件改为 created_date = '0000-00-00' 或 created_date = '0000-00-00 00:00:00' 两种写法都试一下。
q4:存储过程返回结果集为空,但我知道某些表有零日期?
a:可能是 created_date 列类型为 timestamp,且零日期被自动转为 null 或 1970-01-01。请先确认实际存储的值,使用 select min(created_date) from table 查看最小日期。
q5:导出的 csv 中文乱码?
a:脚本已使用 utf-8-sig 编码,excel 打开时应正常。若仍乱码,可尝试用 wps 或 记事本 另存为 utf-8 格式。
推荐流程:
数据修复建议(仅供参考):
-- 将零日期更新为 null(需确认业务是否允许) update table_name set created_date = null where created_date = '0000-00-00 00:00:00'; -- 或更新为有效默认值(如 1970-01-01) update table_name set created_date = '1970-01-01 00:00:00' where created_date = '0000-00-00 00:00:00';
操作前请务必备份数据。
长期防范:在应用层禁止插入零日期,或在数据库层面设置 sql_mode = 'strict_trans_tables,no_zero_date' 以强制拒绝。
到此这篇关于mysql数据库如何快速查找表中零日期记录的文章就介绍到这了,更多相关mysql查找零日期记录内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论