1、Mnesia提供了如下几个函数遍历所有记录
这些函数会将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)).