微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Oracle约束-比较两个字符串两次

如何解决Oracle约束-比较两个字符串两次

我想创建表witj约束,该约束将两个varchar2(8 char)列作为时间进行比较。 有可能吗?

我已经做出了这样的想法,但是它不起作用:(

CONSTRAINT "my_constraint" CHECK (to_number(to_char(to_date(window_stop,'hh24:mi:ss'),'sssss')) > to_number(to_char(to_date(window_start,'sssss'))) ENABLE

感谢所有帮助。 保罗。

解决方法

正如我所说,将varchar2用于日期字段始终是一个非常糟糕的主意。让我向您展示当字段为日期时约束如此简单

SQL> create table t ( c1 date,c2 date ) ;

Table created.

SQL> alter session set nls_date_format='dd.mm.yyyy hh24:mi:ss' ;

Session altered.

SQL> insert into t values ( to_date('11.08.2020 14:00:00'),to_date('11.08.2020 14:10:00') ) ;

1 row created.

SQL> commit ;

Commit complete.

SQL> select * from t ;

C1                  C2
------------------- -------------------
11.08.2020 14:00:00 11.08.2020 14:10:00

SQL> select ( c2 - c1 ) * 24 * 60 * 60 from t ;

(C2-C1)*24*60*60
----------------
             600

现在,让我们添加约束

SQL> alter table t add constraint chk_test check ( c2 > c1 ) ;

Table altered.

SQL> insert into t values ( to_date('11.08.2020 14:11:00'),to_date('11.08.2020 14:10:00') ) ;
insert into t values ( to_date('11.08.2020 14:11:00'),to_date('11.08.2020 14:10:00') )
*
ERROR at line 1:
ORA-02290: check constraint (SYS.CHK_TEST) violated

您要存储时间(即日期),并且要比较window_stop大于window_start。无需进行复杂的转换,只需将字段存储为日期即可。尽管事实是您要存储的数据的正确数据类型,但约束将工作得更好。

,

您的约束将得到“ ORA-02436:日期或系统变量在CHECK约束中错误指定”,因为如果不提供日期元素,则to_date()默认为当月的第一天;因此,在插入数据后,评估约束检查的结果可能会更改,这是不允许的。在这种特定情况下,它实际上无法更改,但是正在应用通用规则,从而导致错误。

您可以改用名义上的固定日期

CONSTRAINT "my_constraint"
  CHECK (
      to_number(to_char(to_date('2000-01-01 ' || window_stop,'YYYY-MM-DD hh24:mi:ss'),'sssss'))
    > to_number(to_char(to_date('2000-01-01 ' || window_start,'sssss'))
  ) ENABLE

db<>fiddle

不过,转换为数字并没有多大意义,只需比较一下日期即可:

CONSTRAINT "my_constraint"
  CHECK (
      to_date('2000-01-01 ' || window_stop,'YYYY-MM-DD hh24:mi:ss')
    > to_date('2000-01-01 ' || window_start,'YYYY-MM-DD hh24:mi:ss')
  ) ENABLE

db<>fiddle

或者-如果您确信值将始终是有效时间并且将带有前导零,则只需比较字符串即可:

CONSTRAINT "my_constraint" CHECK (window_stop > window_start) ENABLE

db<>fiddle

您还可以将时间存储为标称日期,午夜后的秒数或时间间隔,这样可以更轻松地防止使用完全无效的值(例如“ 99:00:00”)。但是您可能有一个可以代替的真实日期-取决于这些日期是否与真实日期相关联,例如移位模式或类似模式-可使您处理午夜时分穿过的窗户。 (您应该要做的是将相关的日期和时间存储在单独的字段中,但没有迹象表明您在这里做什么。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。