【问题标题】:SQL DEVELOPER: Add time to date formatSQL DEVELOPER:添加时间到日期格式
【发布时间】:2022-01-18 00:18:31
【问题描述】:

我的数据库中有一个表,其中包含属性开始和结束时间。 它们的日期格式为“DD/MM/YYYY HH24: MI: SS”。 我想为结束时间添加一个默认值,即开始时间加上 45 分钟的结果。 有谁知道如何实现?

亲切的问候

enter image description here

【问题讨论】:

  • 嗨。请编辑问题并显示准确的表定义(列、数据类型)、准确的样本数据以及该数据的预期输出。
  • 我认为您需要使用 BEFORE INSERT 触发器来执行此操作。
  • 我添加了一张显示代码的图片。
  • DEFAULT 表达式不能包含对另一列的引用 - 这在文档中已明确说明。正如 OldProgrammer 所说,您将需要一个触发器。此外,请注意您的 CREATE 语句还有其他错误 - 我注意到顶部有一个错误,您应该有 CREATE TABLE ...(您缺少强制关键字 TABLE)。
  • “我添加了一张显示代码的图片” 许多网站出于安全原因阻止了此类链接。许多论坛成员出于同样的原因拒绝打开它们。没有什么能阻止您将图像直接粘贴到您的帖子中。除此之外,最好将代码发布为作为文本,以便人们可以将其复制并粘贴到他们自己的系统中进行测试。请参阅[最小可重现示例]{stackoverflow.com/help/minimal-reproducible-example}

标签: sql oracle


【解决方案1】:

使用BEFORE INSERT 触发器并在结束时间为NULL 时将间隔文字添加到开始时间:

CREATE TRIGGER lesson_default_endtime
  BEFORE INSERT ON lesson
  FOR EACH ROW
DECLARE
BEGIN
  IF :new.endtime IS NULL THEN
    :new.endtime := :new.starttime + INTERVAL '45' MINUTE;
  END IF;
END;
/

如果你:

-- Default value
INSERT INTO lesson (starttime, endtime) VALUES (DATE '2021-01-01', NULL);

-- Non-default value
INSERT INTO lesson (starttime, endtime) VALUES (DATE '2021-01-01', DATE '2021-01-01' + INTERVAL '1' HOUR);

然后:

SELECT starttime, endtime FROM lesson;

输出:

STARTTIME ENDTIME
2021-01-01 00:00:00 2021-01-01 00:45:00
2021-01-01 00:00:00 2021-01-01 01:00:00

db小提琴here

【讨论】:

    【解决方案2】:

    您可以使用VIRTUAL 列代替DEFAULT

    virtual column 永远不会被插入,而是从给定的公式中选择计算出来的。

    示例

    create table lesson
    (starttime DATE,
     endtime DATE generated always as (starttime +  INTERVAL '45' MINUTE) virtual
     );
     
    insert into lesson(starttime) values(sysdate);
     
    select * from lesson; 
    
    STARTTIME           ENDTIME            
    ------------------- -------------------
    14.12.2021 19:11:34 14.12.2021 19:56:34
    

    带有虚拟列的真实默认值

    如果您希望能够覆盖默认值并更改课程的长度 - 添加另一个具有异常结束时间的列并调整公式。

    create table lesson
    (starttime DATE,
     endtime_exept DATE,
     endtime DATE generated always as (
        case when endtime_exept is null then starttime +  INTERVAL '45' MINUTE else endtime_exept end
        ) virtual
     );
     
    insert into lesson(starttime) values(to_date('14.12.2021 10','dd.mm.yyyy hh24'));
     
    select starttime, endtime from lesson; 
    
    STARTTIME           ENDTIME            
    ------------------- -------------------
    14.12.2021 10:00:00 14.12.2021 10:45:00
    
    -- prolong the lesson
    update lesson
    set endtime_exept = to_date('14.12.2021 11','dd.mm.yyyy hh24');
    
    select starttime, endtime from lesson;
    
    STARTTIME           ENDTIME            
    ------------------- -------------------
    14.12.2021 10:00:00 14.12.2021 11:00:00
    

    【讨论】:

    • 这不等同于默认值,因为endtime 不能设置为开始时间后 45 分钟以外的值。
    • 采用了解决方案以涵盖在不使用我不喜欢@MT0 的触发器的情况下更改 deaflt 值的可能性
    • @MarmiteBomber 现在您在表中携带了一个额外的列,它可能对应用程序没有功能价值,不是吗?怎么比触发器更干净?
    • extra确实有功能意义,表示如果填满 - 本课例外,不适合在网格中。它将 IMO 保持 99.9% 为空(我的学校经验),因此您不仅可以节省空间,而且可以仅通过更新开始时间来移动标准时间。我并不是说触发器不好@OldProgrammer 我不喜欢它们。
    猜你喜欢
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    相关资源
    最近更新 更多