2010-05-26 18 views
6

Tôi có bảng kiểu Mnesia có các trường là f1, f2, f3. Bây giờ nếu tôi chọn tất cả các hàng có giá trị trường là V1, tôi sẽ sử dụng mnesia:select và thông số kỹ thuật phù hợp hoặc đơn giản mnesia:match_object. Bây giờ tôi cần phải chọn tất cả các hàng có V1, V2, V3 ... hoặc Vn (một danh sách chiều dài tùy ý) làm giá trị cho trường f1. Trong SQL, tôi sẽ làm điều gì đó nhưErlang Mnesia Tương đương với SQL Chọn FROM WHERE Field IN (giá trị 1, giá trị2, giá trị3, ...)

SELECT * FROM tablename WHERE f3 IN (V1, V2, V3, ... , Vn) 

Làm cách nào để thực hiện việc này trong chứng mất trí?

Trả lời

5

Và đối với giải pháp khớp-spec cho vấn đề này, nếu QLC được đo là không đủ hiệu quả.

> ets:fun2ms(fun ({_,X}=E) when X == a -> E end). 
[{{'_','$1'},[{'==','$1',a}],['$_']}] 

Các ETS: fun2ms là một phân tích cú pháp chuyển đổi mà có thể dịch một số funs vào giá trị matchspec. Tôi sử dụng nó như là một cách nhanh chóng để có được matchspec tôi muốn. Chúng tôi nhận được một danh sách với một matchspec mà tìm thấy một tuple nơi yếu tố thứ hai là một. Chúng ta có thể lặp lại nó cho các phím khác.

Vì vậy, hãy điền một bảng điều khiển với một cái gì đó để thử điều này, sau đó tạo một matchspec chỉ khớp với các mục có phần tử thứ hai là 'a' hoặc 'c'. (Tôi nhập này

ets:new(foo, [named_table]). 

ets:insert(foo, [{1,a},{2,b},{3,c},{4,d}]). 

Vs = [a,c]. 

MS = [{{'_','$1'},[{'==','$1',V}],['$_']} || V <- Vs]. 

ets:select(foo, MS). 

Khi tôi chạy này, tôi nhận được:

[{1,a},{3,c}] 
2

Nếu bạn cần truy vấn "phức tạp" thì QLC là cách ngắn gọn để nêu rõ chúng. QLC là một phép chuyển đổi phân tích cú pháp cho phép bạn sử dụng cú pháp đọc danh sách trên các bảng khác nhau, bao gồm các bảng mnesia.

Bạn phải có những điều sau đây, vì nó cho phép phân tích cú pháp chuyển đổi làm cho QLC có thể trong tệp nguồn này.

-include_lib("stdlib/include/qlc.hrl"). 

Biểu mẫu truy vấn cơ bản trông như sau, tạo truy vấn xử lý và sau đó đánh giá truy vấn.

QH = qlc:q([X || X <- Xs]), 
qlc:eval(QH). 

Sau đó, bạn có thể sử dụng http://www.erlang.org/doc/man/mnesia.html#table-1 để lấy bảng QLC được kết thúc lại trong bảng tính. Vì vậy, truy vấn của bạn có thể được triển khai như sau:

Vs = [V1,V2,...Vn], 
QH = qlc:q([X || X <- mnesia:table(tablename), 
       lists:member(X#tablename.f3, Vs)]), 
qlc:eval(QH). 

Điều này yêu cầu quét bảng, không hiệu quả lắm. Nếu bạn có chỉ mục trên cột f3 thì bạn có thể thay đổi nó xung quanh và truy vấn đầu tiên cho các mục có f3 = V1, sau đó là V2, v.v ... và hợp nhất các kết quả.

PS

Cách khác là tạo một kết hợp khá phức tạp trong danh sách giá trị V và chạy chứng mất trí: chọn.

3

Christian chỉ ra giải pháp tốt đẹp, nhưng nó có thể được thực hiện một chút đơn giản

2> ets:fun2ms(fun ({_,a}=E) -> E end).    
[{{'_',a},[],['$_']}] 

như vậy cho bạn phù hợp với bạn có thể làm cho thông số đối sánh đơn giản hơn

4> ets:new(foo, [named_table]). 
foo 
5> ets:insert(foo, [{1,a},{2,b},{3,c},{4,d}]). 
true 
6> Vs = [a,c]. 
[a,c] 
7> MS = [{{'_',V},[],['$_']} || V <- Vs].     
[{{'_',a},[],['$_']},{{'_',c},[],['$_']}] 
8> ets:select(foo, MS). 
[{1,a},{3,c}] 
Các vấn đề liên quan