TO_DATE函数索引报错ORA-01743

简介: 开发同学有一个需求,如下这张表:CREATE TABLE TBL_EFFDATE(ROUTID NUMBER(20,0) NOT NULL,EFFDTE CHAR(7),EDDATE CHAR(7),ICID CHAR(1),FREQ CHAR(7));其中EFFDTE保存的是DDMONYY格式的日期,由于表之前未有归档机制,因此产生了许多垃圾数据,现在需要根据EFFDTE删除16年以前的所有数据,表的数据量在百万级,16年以前的占了绝大部分。

开发同学有一个需求,如下这张表:

CREATE TABLE TBL_EFFDATE
(ROUTID NUMBER(20,0) NOT NULL,
EFFDTE CHAR(7),
EDDATE CHAR(7),
ICID CHAR(1),
FREQ CHAR(7)
);

其中EFFDTE保存的是DDMONYY格式的日期,由于表之前未有归档机制,因此产生了许多垃圾数据,现在需要根据EFFDTE删除16年以前的所有数据,表的数据量在百万级,16年以前的占了绝大部分。

对于这需求来说,SQL的条件很明确,就是根据EFFDTE来做过滤删除,这里日期字段EFFDTE是字符型,不是DATE型,因此就不能使用判断符直接操作。很容易想到的是使用如下SQL:
这里写图片描述
鉴于数据量比较大,需要使用索引,那么很容易想到的是建立to_date(effdate,’DDMONYY’)的一个函数索引,
这里写图片描述
创建索引报错了,ORA-01743,
这里写图片描述
提示:“只能对纯粹的函数创建索引,SQL表达式不能使用任何依赖于当前session状态的信息”。从这SQL看,没有使用SYSDATE、USER、USERENV()这些函数,为什么还提示这错误?

TOM的书中其实给出了关于ORA-01743的原因,

the YYYY format will return May 1, in June it will return June 1, and so on. It turns out that TO_DATE, when used with YYYY, is not deterministic! That is why the index cannot be created: it would only work correctly in the month you created it in (or insert/updated a row in). So, it is due to the user environment, which includes the current date itself. To use TO_DATE in a function-based index, you must use a date format that is unambiguous and deterministic—regardless of what day it is currently.

原因就是TO_DATE函数中使用了表示年份的YY,对于格式相同的输入,返回的则是不同的结果,有些抽象,结合例子看下,假设今天是1月份,则如下SQL返回的是2010年1月1日(1月1日是因为未指定月日,则做了类似trunc的操作):
这里写图片描述
假设今天是2月份,则如下SQL返回的是2010年2月1日:
这里写图片描述
之所以是结果不同,是因为TO_DATE使用了SYSDATE作为基准来输出的日期,因此SQL其实还是基于了session,所以TO_DATE函数索引会有ORA-01743。

如何解这个问题,换种思路,现在要删除16年以前的数据,或者说是保存16年的数据,那么DDMONYY的YY其实是一个定值,可以创建这个索引,
这里写图片描述
现在用where substr(eddate,-2)=’16’作为条件时就可以用索引了,
这里写图片描述

但如果是使用delete from tbl_effdate直接删除,就可能不是很合适了,一是数据直接删除,万一需要再用,就需要其他备份恢复手段了,另一方面,这要遍历非16的所有年份来做,比较LOW,可以这么做:

create table tbl_effdate_16 as select * from tbl_effdate where substr(eddate,-2)='16';

rename tbl_effdate to tbl_effdate_p;

rename tbl_effdate_16 to tbl_effdate_16;

好处就是,所有数据未真正删除,还可直接恢复,执行时间基本可以控制在秒级。

总结:
1.TO_DATE函数索引的创建是有前提条件,不能依赖现有的session,像YY这种格式,隐含依赖了session,所以还是会报错。
2.数据删除策略,可以选择新建备份表,缩小删除数据范围的方法,一是保存现有数据,二是执行时间有保证。

目录
相关文章
|
存储
Rockchip系列之浅度分析LED状态灯 Driver篇(1)
Rockchip系列之浅度分析LED状态灯 Driver篇(1)
465 2
|
编解码 数据可视化 数据挖掘
matplotlib绘制三维曲面图时遇到的问题及解决方法
本文详细介绍了在使用Matplotlib绘制三维曲面图时可能遇到的问题及其解决方法。从数据维度匹配到颜色映射,从图形显示到保存,涵盖了常见的各种情况。通过正确处理这些问题,可以确保生成高质量的三维可视化图形,为数据分析和展示提供有力支持。希望本文对您在使用Matplotlib进行三维绘图时有所帮助。
458 0
|
9月前
|
存储 算法
算法系列之搜索算法-广度优先搜索BFS
广度优先搜索(BFS)是一种非常强大的算法,特别适用于解决最短路径、层次遍历和连通性问题。在面试中,掌握BFS的基本实现和应用场景,能够帮助你高效解决许多与图或树相关的问题。
807 1
算法系列之搜索算法-广度优先搜索BFS
|
存储 Linux Docker
Docker 修改镜像存储位置(WSL2)
Docker 修改镜像存储位置(WSL2)
384 0
|
物联网 vr&ar Android开发
移动应用与系统:探索现代移动技术的发展趋势####
【10月更文挑战第29天】 本文深入探讨了移动应用开发和移动操作系统的最新趋势,分析了它们对日常生活和行业的影响。随着智能手机的普及和技术的进步,移动应用和操作系统不断进化,以满足用户的需求和期望。文章将通过具体案例和数据分析,揭示这一领域的创新点和未来发展方向。 ####
|
NoSQL Redis
Redis集群伸缩,转移插槽失败
Redis集群伸缩,转移插槽失败解决方法
278 0
|
C++ 编译器 Python
Shared_from_this 几个值得注意的地方
shared_from_this()是enable_shared_from_this的成员 函数,返回shared_ptr。首先需要注意的是,这个函数仅在shared_ptr的构造函数被调用之后才能使 用。
2116 0
|
数据管理 BI 定位技术
电话自动拨号软件在电脑上自动拨打
要实现电话自动拨号功勇,几个必备的条件:1、电话自动拨号外呼系统,2、电话机,软件电话如:eyeBeam 硬件电话:IP电话机(强烈推荐用户使用,数字信号,效果好),也可以用网关+模拟电话机来用。3、外呼的线路,也就是营运商提供打电话用的电话线,可以是中继、IMS、手机卡、模拟电话(这种已经慢慢淘汰)。这三样齐了后,就可以实现电话自动拨号功能。对打电话的过程来讲,企业电话自动拨号软件起到了辅助拨号、自动拨号的功能,它省掉了人工按键拨号的过程。下面我们以软件电话eyeBeam我们的外呼系统配合说明自动拨号的的功能。
1606 0
|
数据可视化 安全 Java
QuickBI关于OpenAPI的使用问题梳理及高频需求实现样例
Quick BI企业客户所购买的多为专业版,且企业存在自有oa(办公)系统,组织架构庞大、复杂,系统多,权限分配及管理存在自有的集成系统统一管理,用以做到精准的权限管控。而Quick BI官方提供的OpenAPI提供了多样化的权限控制统一接口用以满足不同企业权限统一且自动化管控的的集成需求,本文针对Quick BI的工作流程、使用方法及限制以及针对高频场景从OpenAPI Explorer到封装python SDK由浅入深的给出了多种调用方式的使用样例。
|
人工智能 程序员
创业之路 - 张一鸣:创业6年,估值750亿美元,人才不是核心竞争力,机制才是
创业之路 - 张一鸣:创业6年,估值750亿美元,人才不是核心竞争力,机制才是
998 0
创业之路 - 张一鸣:创业6年,估值750亿美元,人才不是核心竞争力,机制才是