SQLite触发器:在另一个

时间:2018-10-28 11:55:23

标签: python sql sqlite triggers

我有三个主表来跟踪它们之间的productslocationlogistics,其中包括将产品往返于各个位置的信息。我制作了另一个表balance,以使各个位置的每种产品的数量保持最终平衡。

以下是架构:

products(prod_id INTEGER PRIMARY KEY AUTOINCREMENT,
         prod_name TEXT UNIQUE NOT NULL,
         prod_quantity INTEGER NOT NULL,
         unallocated_quantity INTEGER)

最初,添加产品时,prod_quantity和unallocated_quantity具有相同的值。每次分配一定数量的相应产品时,就会减去unallocated_quantity。

location(loc_id INTEGER PRIMARY KEY AUTOINCREMENT,
         loc_name TEXT UNIQUE NOT NULL)

logistics(trans_id INTEGER PRIMARY KEY AUTOINCREMENT,
          prod_id INTEGER NOT NULL,
          from_loc_id INTEGER NULL,
          to_loc_id INTEGER NOT NULL,
          prod_quantity INTEGER NOT NULL,
          trans_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
          FOREIGN KEY(prod_id) REFERENCES products(prod_id),
          FOREIGN KEY(from_loc_id) REFERENCES location(loc_id),
          FOREIGN KEY(to_loc_id) REFERENCES location(loc_id))

balance(prod_id INTEGER NOT NULL,
        loc_id INTEGER NOT NULL,
        quantity INTEGER NOT NULL,
        FOREIGN KEY(prod_id) REFERENCES products(prod_id),
        FOREIGN KEY(loc_id) REFERENCES location(loc_id))

logistics中进行的每个输入中,我都希望有一个触发器来更新balance中的值,从而保留所有交易的摘要(在位置之间移动产品)

我想到了一种触发解决方案,该解决方案将检查表logistics上的每个插入是否在prod_id, loc_id表中已经存在相同的balance条目,如果存在,则将对其进行更新。适当地。但是,我没有SQLite的实施经验。

1 个答案:

答案 0 :(得分:1)

我相信您的TRIGGER将遵循以下任一条件:-

CREATE TRIGGER IF NOT EXISTS logistics_added AFTER INSERT ON logistics
BEGIN
    UPDATE balance SET quantity = ((SELECT quantity FROM balance WHERE prod_id = new.prod_id AND loc_id = new.from_loc_id) - new.prod_quantity) WHERE prod_id = new.prod_id AND loc_id = new.from_loc_id;
        UPDATE balance SET quantity = ((SELECT quantity FROM balance WHERE prod_id = new.prod_id AND loc_id = new.to_loc_id) + new.prod_quantity) WHERE prod_id = new.prod_id AND loc_id = new.to_loc_id;
END;

或:-

CREATE TRIGGER IF NOT EXISTS logistics_added AFTER INSERT ON logistics
BEGIN
    INSERT OR REPLACE INTO balance VALUES(new.prod_id,new.from_loc_id,(SELECT quantity FROM balance WHERE prod_id = new.prod_id AND loc_id = new.from_loc_id) - new.prod_quantity);
        INSERT OR REPLACE INTO balance VALUES(new.prod_id,new.to_loc_id,(SELECT quantity FROM balance WHERE prod_id = new.prod_id AND loc_id = new.to_loc_id) + new.prod_quantity);
END;

请注意,第二个方法依赖于使用PRIMARY KEY (prod_id,loc_id)或交替使用UNIQUE (prod_id,loc_id) balance 表添加UNIQUE约束。无论如何,可能都需要/希望使用UNIQUE约束。

微妙的区别是,如果不存在适当的行,则第二个将插入余额行。如果没有适当的余额行,那么后者将什么也不做。