Mnesia错误case_clause在没有case子句的QLC查询中

时间:2016-10-08 06:31:08

标签: erlang mnesia

我有一个hacky项目的以下功能:

% The Record variable is some known record with an associated table.
Query = qlc:q([Existing ||
  Existing <- mnesia:table(Table),
  ExistingFields = record_to_fields(Existing),
  RecordFields = record_to_fields(Record),
  ExistingFields == RecordFields
]).

函数record_to_fields/1只是从元组中删除记录名称和ID,以便我可以比较字段本身。如果有人想要上下文,那是因为我在尝试将其插入Mnesia之前为记录预先生成了一个唯一ID,并且我想确保不存在具有相同字段(但ID不同)的记录。

这导致以下(为清晰起见而编辑)堆栈跟踪:

{aborted, {{case_clause, {stuff}},
      [{db, '-my_func/2-fun-1-',8, ...

哪个指向我声明Query的行,但是看不到案例条款。导致此错误的原因是什么?

(会自己回答,但我很感谢能够解释我如何实现我想要的评论)

编辑:如果我只是将某些字段标记为唯一字段,则不需要这样做,而且Mnesia具有专用的insert/1create/1功能。

2 个答案:

答案 0 :(得分:1)

对于您的示例,我认为您的解决方案无论如何都会更清晰(尽管您似乎可以将record_to_fields(Record)部分拉到理解之外,因此不会反复计算。)

是的,列表推导只能有生成器和赋值。但是你可以通过将作业编写为单元素生成器来作弊。例如,您可以将表达式重写为:

RecordFields = record_to_fields(Record),
Query = qlc:q([Existing ||
  Existing <- mnesia:table(Table),
  ExistingFields <- [record_to_fields(Existing)],
  ExistingFields == RecordFields
]).

答案 1 :(得分:0)

事实证明,QLC DSL不允许分配,只允许发生器和过滤器;根据文件(强调我的):

  

语法QLC与普通列表具有相同的部分   推导:

     

[Expression || Qualifier1, Qualifier2, ...]

     

表达(模板)   是任何Erlang表达式。 限定符是过滤器或生成器。   过滤器是返回boolean() 的Erlang表达式。发电机有   表单Pattern <- ListExpression,其中ListExpression是一个   表达式求值为查询句柄或列表。

这意味着我们无法在QLC查询中进行变量分配。

因此,就我所知,我唯一的选择是简单地将查询写成:

Query = qlc:q([Existing ||
  Existing <- mnesia:table(Table),
  record_to_fields(Existing) == record_to_fields(Record)
]).