【问题标题】:Mnesia Errors case_clause in QLC query without a case clause没有 case 子句的 QLC 查询中的 Mnesia 错误 case_clause
【发布时间】:2016-10-10 23:14:37
【问题描述】:

我有一个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 的行,但是看不到case 子句。是什么导致了这个错误?

(我会回答自己,但我很欣赏可以解释我如何实现我想要的东西的评论)

编辑:如果我可以简单地将某些字段标记为唯一,那么这将不是必需的,并且 Mnesia 有一个专用的 insert/1create/1 函数。

【问题讨论】:

    标签: erlang mnesia


    【解决方案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
    ]).
    

    【讨论】:

      【解决方案2】:

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

      从句法上讲,QLC 与普通列表具有相同的部分 理解:

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

      表达式(模板) 是任何 Erlang 表达式。 限定符是过滤器或生成器。 过滤器是 Erlang 表达式返回 boolean()。发电机有 Pattern &lt;- ListExpression 的形式,其中 ListExpression 是 表达式评估为查询句柄或列表。

      这意味着我们不能在 QLC 查询中进行变量赋值。

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

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

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-09
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        • 2018-09-13
        相关资源
        最近更新 更多