【问题标题】:Events based on sysdate [duplicate]基于 sysdate 的事件 [重复]
【发布时间】:2012-12-16 07:07:57
【问题描述】:

可能重复:
Trigger based on sysdate

1.我有一张桌子,我必须在每天 12:00(24 小时制)对其执行更新操作。

我应该如何做到这一点?

表架构:

CREATE TABLE CHARGES   
(
    total NUMBER(30),
    admitdate TIMESTAMP(6),
    dischargedate TIMESTAMP(30)
)

更新算法:

if 
{
   dischargedate="null" 
   then total=admitdate-sysdate=difference in days * Total
   Do this every day at 12:00(24 Hr. Format)
}
else
{  
  do nothing.    
}

【问题讨论】:

  • 这与您的previous question 有何不同?
  • 这个不清楚:then total=admitdate-sysdate=difference in days * Total
  • 你不能每天都运行一个(例如 PHP)脚本吗?使用 PHP CLI 应该不会那么难。
  • 在上一个问题中,它基于触发器,如果​​系统离线时触发器不运行,但我认为触发器不适用于此算法,因此需要一些帮助来完成此任务。 @Mat
  • 是两个日期之间的差数*总计@codingbiz

标签: sql database oracle plsql triggers


【解决方案1】:

每 24 小时运行一次作业的标准是使用系统包DBMS_SCHEDULER 在此时间间隔运行一次作业。

例如:

BEGIN
  DBMS_SCHEDULER.create_job (
    job_name        => 'update_charges',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN my_procedure; END;',
    start_date      => TRUNC(SYSDATE) + 0.5,
    repeat_interval => 'freq=daily;',
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'Update the discharged date in charges.');
END;
/

然后您创建一个要运行的过程:

create or replace PROCEDURE my_procedure is

begin

  update charges
     set total = admitdate - sysdate
   where dischargedate is null;

end;
/

这会将总计列更新为 admitdate 和 SYSDATE 之间的天数。

然而,我怀疑有必要这样做。这听起来很像古老的“我应该存储年龄”问题。 I believe the answer is no. 您在某些时候绝对是错误的,并且有多种可能性可能导致手动错误地运行作业。当您从数据库中提取数据时,我会即时计算此列。

【讨论】:

  • +1,用于提及存储年龄的整个概念。
  • @Ben 这项工作会每天执行吗?如果每天比什么时间执行?
  • 这应该在中午执行(+0.5 部分)并每天执行(freq=daily)。不过,我强烈建议您阅读链接的文档。这很复杂,所以查看some examples 也可能会有所帮助......
【解决方案2】:

表示为SQL,我认为你的算法是在下面的UPDATE 语句中实现的。每次运行算法时,您似乎都想将total 相乘;我假设这是我的误解或你的错字。 total 简单地等于承认日期和当前日期之间的差异似乎更有意义。

UPDATE CHARGES
   SET Total = DATEDIFF(d, GETDATE(), AdmitDate)
 WHERE DischargeDate IS NULL;

为确保此查询高效运行,您需要在 DischargeDate 列上创建索引。

要每天在特定时间执行此操作,您有几个选择。

如果您有自己的服务器代码在运行,一种方法是让该代码安排工作并在您需要时执行它。如果您在服务器端架构中内置了良好的监控和管理功能。

另一种方法是运行 chronat 作业,具体取决于您使用的操作系统。

【讨论】:

  • 我认为 OP 标记了它ORACLE??/
  • OP 表示原始帖子/海报。在这种情况下,是提出问题的人。
【解决方案3】:

Oracle 没有内置调度程序。有几种不同的方法可以解决这个问题。这里有两个:

1) 创建一个通过服务器调度机制运行的 sql 脚本。对于 Unix/Linux,这将是一个 cron 作业。对于 Windows,这将是一个计划任务。

2) 使用 CREATE_JOB 语法创建计划作业:

BEGIN
DBMS_SCHEDULER.CREATE_JOB (
    job_name           =>  'update_charges',
    job_type           =>  'STORED_PROCEDURE',
    job_action         =>  'MYSCHEMA.SOME_PKG.UPDATE_CHARGES',
    start_date         =>  '28-APR-08 12.00.00 PM Australia/Sydney',
    repeat_interval    =>  'FREQ=DAILY;INTERVAL=1', /* every other day */
    end_date           =>  '20-NOV-13 12.00.00 PM Australia/Sydney',
    job_class          =>  'batch_update_jobs',
    comments           =>  'My new job');
END;

【讨论】:

  • 抱歉,是的,但是如果系统在 12:00 @davidethell 离线怎么办
  • 如果系统在 12:00 @Akki 处于离线状态,那你就完全不走运了,这就是为什么我建议不要存储此列。
  • @Akki,如果您在中午 12 点安排日常工作,那么确保服务器在线是服务器管理员的工作。
  • 感谢@davidethell 的回复和回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多