我正在编写监控软件,其中大部分逻辑都在Oracle数据库和数据库中。 PL / SQL。
当我的监控被调用时,它应警告问题。例如,如果,它应警告问题
1。星期五22:00至23:00,每分钟运行不到2次
2。 1月31日22:00-23:00,每分钟运行不到5次
3。从10:00到12:00,每天每分钟操作不到3次
如果我的监控在1月31日22:30召唤,我应该将我的操作号码与5进行比较。
4.如果操作少于5次,则每分钟从星期五22:00到星期一15:00
我正在考虑用数据库中的cron表达格式保存数据周期。在这种情况下,我必须将SYSDATE(监视函数的当前调用日期)与保存在数据库中的cron表达式进行比较。
我的问题:
1.如何判断SYSDATE是否属于cron表达式?
2。在这种情况下使用cron表达式是否正确?你能否建议任何其他节省时间的方法。
答案 0 :(得分:4)
我完全使用SpaceTrucker:不要在SQL或PL / SQL中执行此操作,使用Java 8 date API或JodaTime在Java中执行此操作。
但即使你不应该这样做,也可能有一些很好的理由去做。所以这是如何:
首先,让我们在您要检查的时间间隔内为每秒或分钟创建一个表。间隔的粒度和长度取决于您要允许的cron表达式。通常一周一秒应该足够(大约100&#39,000行)。如果要检查整年,请使用分钟作为粒度(大约500&#39,000行)。数量或行都不适用于现代数据库。在我的笔记本上,根据查询立即返回。
CREATE TABLE week AS
SELECT
running_second,
ts,
EXTRACT(SECOND FROM ts) as sec,
EXTRACT(MINUTE FROM ts) as min,
EXTRACT(HOUR FROM ts) as h,
to_char(ts, 'Day') as dow
FROM (
SELECT
level as running_second,
TO_TIMESTAMP_TZ('2015-09-05 00:00:00 0:00',
'YYYY-MM-DD HH24:MI:SS TZH:TZM') +
NUMTODSINTERVAL(level-1, 'SECOND') AS ts
FROM dual CONNECT BY level<=60*60*24*7
)
;
接下来,将每个cron表达式转换为查询。您可以使用PL / SQL将每个cron表达式转换为where子句,也可以使用泛型where子句。
你应该得到这样的东西:
SELECT
*
FROM
week
WHERE
h =5
AND min=0
AND sec=0;
或通用版本:
SELECT
filter_expression.name, week.ts
FROM
week, filter_expressions
WHERE
(fiter_hour is null or h = filter_hour)
AND (filter_min is null or min = filer_min)
AND (filter_sec is null or sec = filter_sec);
(假设您的过滤器存储在表filter_expressions
中,每个约束类型都有一列,每行都有一个约束参数,如果约束不适用,则为NULL
将结果存储在全局临时表cron_startpoints
中。
将表格cron_startpoints
分组以检查违规行为。您可以计算,周五或午夜有多少场比赛,或者可以检查,这个号码是否合适。
答案 1 :(得分:1)
这取决于你想要多少灵活性。对于您提供此类结构的示例就足够了:
CREATE TABLE monitoring_periods (
id INTEGER NOT NULL PRIMARY KEY,
monit_month VARCHAR2(2),
monit_day VARCHAR(2),
monit_day_of_week VARCHAR(3),
monit_time_from INTERVAL DAY TO SECOND,
monit_time_to INTERVAL DAY TO SECOND,
required_ops INTEGER
);
Here是存储句点和检查sysdate的一些示例。我会避免将cron表达式字面上存储为字符串,因为它需要在查询时解析它。但是,表达式越复杂(类型为5 4,15,22 * / 2 * 1-5&#39;),存储结构越复杂 - 您需要仔细考虑您的要求。
答案 2 :(得分:1)
我曾经有过编写艰难日期计算的任务,其中重复周期和时间为10g。其中包括&#34;本月第二周的星期二,每2个月在上午8点到下午2点之间#34;我们决定使用java存储过程(也因为它们已经用于其他目的)。
根据您的oracle版本,您可以选择joda-time版本,该版本可以在oracle数据库jvm中运行。另请注意,joda-time 1.6可以使用java 1.3编译(我们必须使用它)。
如果您正在寻找明确的cron表达式,那么您在使用oracle数据库jvm中的另一个Java库时也可能做得很好。例如here就是一个:
CronExpression expression = CronExpression.parser()
.withSecondsField(true)
.withOneBasedDayOfWeek(true)
.allowBothDayFields(false)
.parse("0 15 10 L * ?");
assert expression.matches(dateTime);
但是我觉得cron不适合你手边的任务。 Cron是一种指定何时运行作业的方法。但是你需要观察发生的事情。因此,对于您的要求只有不到2个操作,每分钟您可以在第1秒和第2秒或第1个第31秒进行操作并且两者都有效,但它们的cron表达式非常不同。
如果要保存时间段,您还可以查看存储为varchars的ISO 8601 recurinng intervals:
P1Y2M10DT2H30M
在任何情况下,您都需要对要匹配的每一行应用计算。根据有多少行,您可能需要使用一些启发式方法来分析远离满足条件的结果。
在盒子外面思考一下:
你应该质疑你的架构。您列出的要求可以由状态机表示。您可以使用按时间顺序发生的事件来提供它们。如果状态机达到某种不需要的状态,您只需报告该状态即可。但是我怀疑这可以在纯pl / sql中轻松完成。