【问题标题】:How to do Automatic Entry Of Recurring Amounts Using Triggers In SQLite?如何在 SQLite 中使用触发器自动输入经常性金额?
【发布时间】:2012-07-18 07:51:59
【问题描述】:

一个关于在 SQLite 中使用触发器进行自动更新的棘手问题...

我在这里遇到一种情况,我需要从特定日期开始以特定间隔在表格中输入条目。 “Category”表中的每个类别都有一个“RecurAmount”,设置为以 4 个固定间隔之一重复:7 天、14 天、1 个月、1 年。 (我用整数 1,2,3,4 表示这些)每个类别都有一个 RecurDate,它最初是由用户选择的。一旦这个日期过去,我需要让应用程序执行以下操作(例如,假设应用程序几个月没有打开并且需要刷新):

1) 从 Category 中选择所有类别,其中 RecurDate

2) 插入“Costs”表RecurAmountRecurDateCatKeyRecur 值取自“Categories”表到以下 Costs 列:AmountCostDate、* CatFK*、AutoExp

3) 然后我需要能够让 SQLite 以“Recur”值确定的间隔自动将定期间隔日期的金额插入 Costs 表.因此,如果它的 Recur 值为“1”,我需要从 RecurDate 开始每隔 7 天在 Costs 表中输入一系列条目,并且到今天为止,但不会更远。

4) 一旦所有类别都将其经常性成本实体应用到当前日期...我需要将一个未来日期添加到 CategoryRecurDate 字段中/strong> 表。这将作为下一个自动输入发生之前需要匹配或传递的下一个日期。

以下是我使用的表格: “类别”表:

RecurDate       Key      RecurAmount    Recur   RecurInterval
2012-06-26      20       100            1            Weekly
2012-07-18       21        200          1            Weekly
2012-07-10       22        250          3            Monthly
2012-08-10       22        300          3            Monthly
2012-07-16       23        200          2            Fortnightly
2012-06-20       24       100           4             Yearly

费用”表。这是以固定日期间隔接收插入金额的表。 假设今天的日期是 2012-07-18,当我在很长一段时间后启动应用程序时没有这样做......我需要将 Costs 表更新为如下内容:

CostDate    CatFK       Amount      AutoExp

2012-06-26    20          100       1       
2012-07-03    20          100       1
2012-07-10    20          100       1
2012-07-17    20          100       1
2012-07-18    21          200       1
2012-07-10    22          250       3
2012-07-16    23          200       2
2012-06-20    24          100       4

到目前为止,这是我的代码的开始,它试图仅完成每周的经常性费用。它显然不起作用......

PRAGMA recursive_triggers = on
CREATE TEMPORARY TRIGGER MyTrigger
BEFORE INSERT ON Costs
WHEN new.RecurDate < (select date('now','localtime')) BEGIN
INSERT INTO Costs (CostDate, Amount, CatFK, AutoExp)
VALUES (date(new.RecurDate,'+'||7||' days'), Category.RecurAmount, Category.Key,    Category.Recur;
END

INSERT INTO Costs (CostDate, Amount, CatFK, AutoExp)
SELECT RecurDate, RecurAmount,Key, Recur from Category
WHERE
Recur =1 ;

如您所见,我正在以某种方式使用触发器来完成此任务,但距离完成此任务还有很长的路要走。复杂性来自我正在处理的不同的重复间隔,并根据这些不同的间隔识别未来的“RecurDate”并将其插入到类别表中。我几乎在想我在 SQLite 之外使用 AS3 和一个循环来构建一个自定义语句来锻炼日期,然后将我需要的内容插入到 SQLite 中。

我想知道是否有人可以给我一些指示,因为这很棘手而且我不是很好:)

谢谢

马可

【问题讨论】:

    标签: sql sqlite triggers


    【解决方案1】:

    我认为主要问题是如何根据每行的 RecurDate 值在 CostDate 和今天的日期之间生成必要的 CostDate 值。

    我对SQLlite一无所知,但我可以在SQL server中解决问题,所以我会尝试解释所需的逻辑。

    我建议分 4 次执行此操作,每个刷新周期执行一次。因此,我将在下面的叙述中假设,我们正在创建重复周期为每 7 天的新行。您应该能够根据需要复制其他周期的逻辑。

    您需要一个整数值(天数)的临时表,从 0(=最早的 RecurDate)到今天(包括今天)。因此,例如,如果最早的日期是 142 天前,则该表将需要包含 0 到 142 的值;或者,如果我们可以假设最早可能的 RecurDate 是 1000 天前或更短时间(即接近 3 年前),我们可以说该表将始终需要包含 0 到 1000 的值。

    要创建这个,我不确定你需要什么语法,但我会这样做:

        create table Days (interval int);
        insert Days values (0);
        insert Days values (1);
    
        declare @offset int, @max int;
        select @offset = 2, @max = 1000  /*(1000 per the assumption of a maximum value)*/
        while @offset < @max begin
          insert Days 
          select interval + @offset 
          from Days 
          where interval + @offset <= @max
        end
    

    此表中的数据需要与插入语句中的类别交叉连接(即创建一个笛卡尔积,其中第一个表中的所有行都匹配另一个表中的所有行)创建新行:

        insert costs (Amount, CostDate, CatFK, AutoExp)
        select c.RecurAmount, c.RecurDate + d.interval, c.Catkey, c.Recur
        from Categories c cross join Days d
        where c.RecurDate < getdate()      /*'now'*/
          and c.Recur = 1
          and c.RecurDate + d.interval <= getdate()
          and d.interval > 0
          and d.interval mod 7 = 0;
    

    因此,我们在成本表中插入类别表列 + 期间,对于 RecurDate 在今天之前的所有类别,并且重复间隔为 1(每周),并且 RecurDate + 使用期间小于或等于今天的日期, 并且句点不是 0(因此您不会创建日期 = RecurDate 的记录),并且用于每个插入的句点可以被 7 整除。

    我假设(或者我读错了)在此过程运行后,RecurDate 将根据每个类别的成本中最近的 CostDate 进行更新。

    希望这会有所帮助 :-) JB

    【讨论】:

    • 嗨,John 感谢您的详细回复,这似乎是一种有趣的尝试方法,似乎并不太复杂。我会看看我是否可以让它在 SQLite 中工作。
    • 我对 SQLite 进行了一些调整:我将 getdate() 更改为 julianday('now','localtime') 并将 d.interval>0 更改为 d.interval >= 0为了获得输入的第一个日期。感谢您的帮助约翰。米
    • 不用担心,很高兴我能帮上忙
    猜你喜欢
    • 2019-04-12
    • 2014-11-10
    • 2011-09-28
    • 2015-02-17
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2021-05-07
    • 2016-06-02
    相关资源
    最近更新 更多