没有 case 子句的 QLC 查询中的 Mnesia 错误 case_clause
Mnesia Errors case_clause in QLC query without a case clause
我有一个 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/1
或 create/1
函数。
事实证明,QLC DSL 不允许赋值,只允许生成器和过滤器;根据文档(强调我的):
Syntactically QLCs have the same parts as ordinary list
comprehensions:
[Expression || Qualifier1, Qualifier2, ...]
Expression (the template)
is any Erlang expression. Qualifiers are either filters or generators.
Filters are Erlang expressions returning boolean()
. Generators have
the form Pattern <- ListExpression
, where ListExpression
is an
expression evaluating to a query handle or a list.
这意味着我们不能在 QLC 查询中进行变量赋值。
因此,据我所知,我唯一的选择就是将查询简单地写成:
Query = qlc:q([Existing ||
Existing <- mnesia:table(Table),
record_to_fields(Existing) == record_to_fields(Record)
]).
对于您的示例,我认为您的解决方案无论如何都更加清晰(尽管您似乎可以将 record_to_fields(Record)
部分拉到理解之外,这样就不会一遍又一遍地计算它。)
是的,列表推导只能有生成器和赋值。但是您可以通过将作业编写为单元素生成器来作弊。例如,您可以将表达式重写为:
RecordFields = record_to_fields(Record),
Query = qlc:q([Existing ||
Existing <- mnesia:table(Table),
ExistingFields <- [record_to_fields(Existing)],
ExistingFields == RecordFields
]).
我有一个 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/1
或 create/1
函数。
事实证明,QLC DSL 不允许赋值,只允许生成器和过滤器;根据文档(强调我的):
Syntactically QLCs have the same parts as ordinary list comprehensions:
[Expression || Qualifier1, Qualifier2, ...]
Expression (the template) is any Erlang expression. Qualifiers are either filters or generators. Filters are Erlang expressions returning
boolean()
. Generators have the formPattern <- ListExpression
, whereListExpression
is an expression evaluating to a query handle or a list.
这意味着我们不能在 QLC 查询中进行变量赋值。
因此,据我所知,我唯一的选择就是将查询简单地写成:
Query = qlc:q([Existing ||
Existing <- mnesia:table(Table),
record_to_fields(Existing) == record_to_fields(Record)
]).
对于您的示例,我认为您的解决方案无论如何都更加清晰(尽管您似乎可以将 record_to_fields(Record)
部分拉到理解之外,这样就不会一遍又一遍地计算它。)
是的,列表推导只能有生成器和赋值。但是您可以通过将作业编写为单元素生成器来作弊。例如,您可以将表达式重写为:
RecordFields = record_to_fields(Record),
Query = qlc:q([Existing ||
Existing <- mnesia:table(Table),
ExistingFields <- [record_to_fields(Existing)],
ExistingFields == RecordFields
]).