Oracle中日期字段未定义日期类型的案例补充说明

Posted bisal(Chen Liu)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle中日期字段未定义日期类型的案例补充说明相关的知识,希望对你有一定的参考价值。

Oracle中日期字段未定义日期类型的案例一则》讲到一个用字符串类型的日期字段做分区键的案例,因为这种"不规范"的设计,通过增加一个虚拟列,才实现的日期分区的功能。

原始建表语句,这种不能按照常规的日期数据实现分区,

CREATE TABLE customer(age NUMBER, birthday char(20))
PARTITION BY RANGE (birthday)
(
  PARTITION p1 VALUES less than (to_date('2022-01','yyyy-mm')),
  PARTITION p2 VALUES less than (to_date('2022-02','yyyy-mm')),
  PARTITION p3 VALUES less than (to_date('2022-03','yyyy-mm'))
);

改造成增加一个虚拟列的建表语句,

CREATE TABLE customer(age NUMBER, birthday char(20), partiton_key DATE GENERATED ALWAYS AS (to_date(birthday, 'yyyy-mm-dd')))
PARTITION BY RANGE (partiton_key)
(
  PARTITION p1 VALUES less than (to_date('2022-01','yyyy-mm')),
  PARTITION p2 VALUES less than (to_date('2022-02','yyyy-mm')),
  PARTITION p3 VALUES less than (to_date('2022-03','yyyy-mm'))
);

此时虽然能实现正常的日期分区的功能,但是每次插入INSERT,必须带着除虚拟列外其他的字段,给开发增加了复杂度,

SQL> insert into customer values(1, '2022-01-01');
insert into customer3 values(1, '2022-01-01')
            *
ERROR at line 1:
ORA-00947: not enough values


INSERT INTO customer(age, birthday) values(1, '2022-01-01');

实际上,有时候我们日常的生活中,碰到一个问题,往往可能高估他的难度,或者在潜意识当中认为需要用特殊的方案才可以解决,但实际上,可能最简单的方案就在眼前,这个案例,就是如此。

分区条件直接用字符串,不用to_date(),无论是采用"月",还是"日",

CREATE TABLE customer1(age NUMBER, birthday char(20))
PARTITION BY RANGE (birthday)
(
  PARTITION p1 VALUES less than ('2022-01'),
  PARTITION p2 VALUES less than ('2022-02'),
  PARTITION p3 VALUES less than ('2022-03')
);


CREATE TABLE customer2(age NUMBER, birthday char(20))
PARTITION BY RANGE (birthday)
(
  PARTITION p1 VALUES less than ('2022-01-01'),
  PARTITION p2 VALUES less than ('2022-02-01'),
  PARTITION p3 VALUES less than ('2022-03-01')
);

如下插入语句,都是能执行的,

INSERT INTO customer1 values(1, '2022-01-01');
INSERT INTO customer1 values(1, '2022-02-01');
INSERT INTO customer1 values(2, '2022-02-02');


INSERT INTO customer2 values(1, '2022-01-01');
INSERT INTO customer2 values(1, '2022-02-01');
INSERT INTO customer2 values(2, '2022-02-02');

而且分区数据,都是正确的,这是按照"月"的,

SQL> SELECT * FROM customer1;
       AGE BIRTHDAY
---------- --------------------
         1 2022-01-01
         1 2022-02-01
         2 2022-02-02


SQL> SELECT * FROM customer1 PARTITION(p2);
       AGE BIRTHDAY
---------- --------------------
         1 2022-01-01


SQL> SELECT * FROM customer1 PARTITION(p3);
       AGE BIRTHDAY
---------- --------------------
         1 2022-02-01
         2 2022-02-02

这是按照"天"的,

SQL> SELECT * FROM customer2;
       AGE BIRTHDAY
---------- --------------------
         1 2022-01-01
         1 2022-02-01
         2 2022-02-02


SQL> SELECT * FROM customer2 PARTITION(p2);
       AGE BIRTHDAY
---------- --------------------
         1 2022-01-01


SQL> SELECT * FROM customer2 PARTITION(p3);
       AGE BIRTHDAY
---------- --------------------
         1 2022-02-01
         2 2022-02-02

所以有时候,问题可以先从自身或者最简单的形式考虑,或许就可以得到答案,当然,这还取决于对原理的理解,如果理解到位,可能就脱口而出,否则就会像上面这种,绕道而行,缺练。

近期更新的文章:

GOPS全球运维大会 · 深圳站精彩抢先看!

疫情防控中的数字化

Oracle中日期字段未定义日期类型的案例一则

MySQL中的联合索引、覆盖索引及最左匹配原则

二进制和十六进制的转换操作

文章分类和索引:

公众号900篇文章分类和索引

以上是关于Oracle中日期字段未定义日期类型的案例补充说明的主要内容,如果未能解决你的问题,请参考以下文章

MySQL的TIMESTAMP数据类型

Oracle中日期字段未定义日期类型的案例一则

日期字段未定义DATE类型所带来的一些问题

Graphql 日期字段类型必须是输出类型但得到:未定义

oracle中如何修改日期类型的字段值

oracle 所有的数据类型都有哪些?