1、Mnesia提供了如下几个函数遍历所有记录
mnesia:foldl(Fun, Acc0, Tab) -> NewAcc | transaction abort
mnesia:foldr(Fun, Acc0, Tab) -> NewAcc | transaction abort
mnesia:foldl(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort
mnesia:foldr(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort
这些函数会将Fun遍历应用到表Tab表上,并把结构放入累计集Acc0中,可以按需要指定锁类型。Fun有两个参数,第一个是从表中取出的记录,第二个是累计集。
例如要查找薪资级别在10以下的员工:
find_low_salaries() ->
Constraint =
fun(Emp, Acc) when Emp#employee.salary < 10 ->
[Emp | Acc];
(_, Acc) ->
Acc
end,
Find = fun() -> mnesia:foldl(Constraint, [], employee) end,
mnesia:transaction(Find)
将薪资上调到10级,返回所有涨薪和:
increase_low_salaries() ->
Increase =
fun(Emp, Acc) when Emp#employee.salary < 10 ->
OldS = Emp#employee.salary,
ok = mnesia:write(Emp#employee{salary = 10}),
Acc + 10 - OldS;
(_, Acc) ->
Acc
end,
IncLow = fun() -> mnesia:foldl(Increase, 0, employee, write) end,
mnesia:transaction(IncLow).
在遍历中可以做很多事情,但是要特别留意性能和内存消耗。
2、firecat的实践一,查询数据库表的某一列,并求和
get_onlinenum(<<"ALL_DEVICES">>) -> Mnesia迭代求和
Sum =
fun(Emp, Acc) when Emp#?ONLINE_TAB.onlinenum /= 0 ->
V = Emp#?ONLINE_TAB.onlinenum,
Acc + V;
(_, Acc) ->
Acc
end,
Find = fun() -> mnesia:foldl(Sum, 0, ?ONLINE_TAB) end,
mnesia:transaction(Find);
(test@192.168.83.128)1> test:get_onlinenum(<<"ALL_DEVICES">>).
{atomic,2}
其中,{atomic,2}里面的2就是返回结果。
实践二,修改数据
clear_onlinenum() ->
Clear =
fun(Emp, Acc) when Emp#?ONLINE_TAB.onlinenum /= 0 ->
ok = mnesia:write(Emp#?ONLINE_TAB{onlinenum = 0});
(_, Acc) ->
Acc
end,
Find = fun() -> mnesia:foldl(Clear, [], ?ONLINE_TAB) end,
ret(mnesia:transaction(Find)).