如何记录更改记录?

时间:2019-06-11 23:25:33

标签: java android sqlite

我正在构建一个应用程序,用户可以在其中完成需要其他用户批准的工作。 因此,如果批准者更改(更新)与此记录相关的任何数据,则需要将此更改保存在审核表上,例如https://github.com/spatie/laravel-activitylog

什么是最好的方法?使用触发器实现还是比较对象? Android是否有可以使用它的库?

下面是操作模型:

public class Operation {
    private int id;
    private String started_at;
    private int company_id;
    private int collaborator_id;
    private int approver_id;
    private int building_id;
    private String cost_center;
    private String ended_at;
    private int shift_id;
    private int service_id;
    private String invoice_number;
    private String transport_number;
    private String cod;
    private String lot;
    private int vehicle_id;
    private int carrier_id;
    private String vehicle_plate;
    private String cart_plate;
    private int amount;
    private int loose_cargo;
    private int palletized_load;
    private int gross_weight;
    private String comments;
    private int number_assistants;
    private int number_operators;
    private int number_tractors;
    private int number_samples;
    private int number_others;
}

我正尝试如下创建它:

"CREATE TRIGGER " + OperationEntry.TRIGGER_NAME +
    " AFTER UPDATE " +
    " ON["+ OperationEntry.TABLE_NAME +"] " +
    " FOR EACH ROW " +
    " BEGIN " +
    " DECLARE changes VARCHAR(8000); " +
    " SET changes = '{'; " +
    " IF OLD. " + OperationEntry.COLUMN_ID + " <> " + " NEW. " + OperationEntry.COLUMN_ID + " THEN " +
    "SET changes = CONCAT(changes, );" +
    " END IF; " +
    " IF OLD. " + OperationEntry.COLUMN_COMPANY + " <> " + " NEW. " + OperationEntry.COLUMN_COMPANY + " THEN " +
    "SET changes = CONCAT(changes, );" +
    " END IF; " +
    " IF OLD. " + OperationEntry.COLUMN_BUILDING + " <> " + " NEW. " + OperationEntry.COLUMN_BUILDING + " THEN " +
    "SET changes = CONCAT(changes, );" +
    " END IF; " +
    " SET changes = CONCAT(changes, '}'); " +
    " END; ");

1 个答案:

答案 0 :(得分:3)

使用 AFTER UPDATE TRIGGER似乎很合适,除了生成TRIGGER所需的代码外,不需要其他代码。

问题在于TRIGGER的存在并不明显,但是可以通过在代码内进行适当的注释来克服该缺点。

re:-

  

我正尝试如下创建它:

"CREATE TRIGGER " + OperationEntry.TRIGGER_NAME +
    " AFTER UPDATE " +
    " ON["+ OperationEntry.TABLE_NAME +"] " +
    " FOR EACH ROW " +
    " BEGIN " +
    " DECLARE changes VARCHAR(8000); " +
    " SET changes = '{'; " +
    " IF OLD. " + OperationEntry.COLUMN_ID + " <> " + " NEW. " + OperationEntry.COLUMN_ID + " THEN " +
    "SET changes = CONCAT(changes, );" +
    " END IF; " +
    " IF OLD. " + OperationEntry.COLUMN_COMPANY + " <> " + " NEW. " + OperationEntry.COLUMN_COMPANY + " THEN " +
    "SET changes = CONCAT(changes, );" +
    " END IF; " +
    " IF OLD. " + OperationEntry.COLUMN_BUILDING + " <> " + " NEW. " + OperationEntry.COLUMN_BUILDING + " THEN " +
    "SET changes = CONCAT(changes, );" +
    " END IF; " +
    " SET changes = CONCAT(changes, '}'); " +
    " END; ");

我认为以上大部分内容都不起作用。在SQLITE的SQL实现中没有DECLARE关键字,并且 IF 关键字非常有限。

串联值也很麻烦。

我建议您根据自己的尝试考虑以下几点:-

-- Drop tables and triggers (allows rerunability for testing)
DROP TABLE IF EXISTS OperationEntry;
DROP TABLE IF EXISTS OperationEntryChanges;
DROP TRIGGER IF EXISTS OperationEntryTrigger;

-- Create the original/core table
CREATE TABLE IF NOT EXISTS OperationEntry (
    id INTEGER PRIMARY KEY, 
    company TEXT,   building TEXT
);
-- Create the logging table
CREATE TABLE IF NOT EXISTS OperationEntryChanges (
    oldid INTEGER, 
    newid INTEGER, 
    oldcompany TEXT, 
    newcompany TEXT, 
    oldbuilding TEXT, 
    newbuilding TEXT, 
    timestamp DEFAULT CURRENT_TIMESTAMP, -- assumes that you want some indications of when the update was made
    updatecounter DEFAULT 0 -- maybe over the top/not required may replace or compliment timestamp
    );
-- Create the logging trigger
CREATE TRIGGER OperationEntryTrigger
    AFTER UPDATE  ON OperationEntry
        BEGIN 
            INSERT INTO OperationEntryChanges 
                (oldid, newid, oldcompany, newcompany, oldbuilding, newbuilding, updatecounter) 
            VALUES
                (old.id, new.id, old.company, new.company, old.building, new.building, (SELECT count(*) + 1 FROM OperationEntryChanges)
                );
        END
;

-- Add some testing data
INSERT INTO OperationEntry (company, building) VALUES
        ('company1','Building1'),('company1','Building2'),('company1','Building3'),('company1','Building4'),
        ('company2','Building1'),('company2','Building2'),('company2','Building3'),
        ('company3','Building1'),('company3','Building2'),('company3','Building3'),('company3','Building4'),('company3','Building5')
;

-- Show the data prior to any updates
SELECT * FROM OperationEntry;
SELECT * FROM OperationEntryChanges;

-- Apply some updates
UPDATE OperationEntry SET company = company || 'A' WHERE Building = 'Building2';
UPDATE OperationEntry SET building = replace(building,'Building','Bldg') WHERE building = 'Building5';
UPDATE OperationEntry SET building = building||'X', company = company||'X' WHERE company = 'company1' AND building = 'Building3';

-- Show the data post updates
SELECT * FROM OperationEntry;
SELECT * FROM OperationEntryChanges;
-- Show the changes made
SELECT 
  datetime(timestamp),
    updatecounter,
    CASE 
      WHEN oldcompany <> newcompany AND oldbuilding <> newbuilding THEN 'Company changed from '|| oldcompany || ' to ' || newcompany || ', also Building changed from ' || oldbuilding || ' to ' || newbuilding
        WHEN oldcompany <> newcompany THEN 'Company changed from '|| oldcompany || ' to ' || newcompany 
      WHEN oldbuilding <> newbuilding THEN 'Building changed from ' || oldbuilding || ' to ' || newbuilding END AS changemade
FROM OperationEntryChanges
;

以下将是结果:-

结果1

加载数据后的核心表:-

enter image description here

结果2

加载数据后的更改/日志表(即为空,因为没有更新)

enter image description here

结果3

已更改的核心表(更改已突出显示)

enter image description here

结果4

更改日志表(在全部5次更新(更改了6个值)之后)

![enter image description here

结果5

以更人性化的格式所做的更改

enter image description here