我的数据库中有一个名为stockpricehistory的表,它跟踪库存物品的价格变化,并包含以下数据:
DateStart默认为CURRENT_TIMESTAMP,而DateEnd默认为空,好像没有DateEnd值,那么该行中的价格就是当前库存中的价格。
现在,我怎么能(我通过触发器推测它)使得每当我为特定库存物品插入新行时,它会更新该库存物品的最后一行(即匹配的行)那个库存项,其中DateEnd设置为NULL)以匹配刚刚为要插入的新行的DateStart值,如下所示:
这是表格的初始状态:
然后,当为该库存项目(ID 1)插入新行时,结果如下:
1,4.99,2013-11-20 12:00:00,NULL
1,2.99,2013-11-19 18:49:24,2013-11-20 12:00:00
理论上,它应该只需要更新一行,因为每个股票ID只有一行没有结束日期,即具有当前价格的行。
我认为它将通过BEFORE INSERT触发器完成,但我很可能错了。
答案 0 :(得分:0)
在存储的函数或触发器中,不允许修改a 已经被使用(用于读或写)的表 调用函数或触发器的语句。
从插入位置插入后,您始终可以进行更新。
要更新它,你可以这样做:
UPDATE stockpricehistory s
INNER JOIN (
SELECT stockID,
MAX(dateStart) AS maxDate
FROM stockpricehistory
WHERE StockID = 1
AND DateEnd IS NULL
) a ON s.StockID = a.StockID
SET s.dateEnd = a.maxDate
WHERE s.DateEnd IS NULL
AND s.dateStart != a.maxDate
这是为了让你更新其中一个有dateEnd NULL的行,而不是那个有max(dateStart)的行。
希望它有所帮助。
答案 1 :(得分:0)
正如@Filipe Silva所说,你无法修改在该表上调用的触发器中的表。
您可以通过为股票和股票价格历史记录提供单独的表来解决这个问题,这在任何情况下都可能是一个好主意。 stock
表每个库存项目保留一行及其当前价格,并且当stockpricehistory
中的行插入或更新时,该表上的触发器会保留stock
中的记录。
http://sqlfiddle.com/#!2/55c626/1
create table stock (
stockId int primary key,
price numeric(5, 2));
create table stockpricehistory (
stockId int,
price numeric(5,2),
dateStart datetime,
dateEnd datetime);
create trigger t_si before insert on stock
for each row
insert into stockpricehistory values (new.stockId, new.price, current_timestamp, null);
create trigger t_su before update on stock
for each row begin
update
stockpricehistory
set
dateEnd = current_timestamp
where
stockId = new.stockId and
dateEnd is null;
insert into stockpricehistory values (new.stockId, new.price, current_timestamp, null);
end;