我也遇到了同样的问题,四处寻找,最后想出了自己的方法。这纯粹只是为人们指出正确的方向,为自己找到解决方案。注意:我尝试过 jiffy,但由于我使用的是 rebar3,它目前不兼容。
我使用 MS sql 服务器,所以我使用 Erlang odbc 模块:http://erlang.org/doc/man/odbc.html
odbc:sql_query/2 还给我{selected, Columns, Results}
从这里我可以获取Columns,它是一个字符串列表和结果,一个行列表表示为一个元组,然后创建一些函数来输出有效的 Erlang 代码,以便能够基于一个正确序列化到 Json因素的数量。这是完整的代码:
进行初始查询:
Sql = "SELECT * FROM alloys;",
Ref = connect(),
case odbc:sql_query(Ref, Sql) of
{selected, Columns, Results} ->
set_json_from_sql(Columns, Results, []);
{error, Reason} ->
{error, Reason}
end.
那么输入函数是set_json_from_sql/3,它调用以下函数:
format_by_type(Item) ->
if
is_list(Item) -> list_to_binary(io_lib:format("~s", [Item]));
is_integer(Item) -> Item;
is_boolean(Item) -> io_lib:format("~a", [Item]);
is_atom(Item) -> Item
end.
json_by_type([H], [Hc], Data) ->
NewH = format_by_type(H),
set_json_flatten(Data, Hc, NewH);
json_by_type([H|T], [Hc|Tc], Data) ->
NewH = format_by_type(H),
NewData = set_json_flatten(Data, Hc, NewH),
json_by_type(T, Tc, NewData).
set_json_flatten(Data, Column, Row) ->
ResTuple = {list_to_binary(Column), Row},
lists:flatten(Data, [ResTuple]).
set_json_from_sql([], [], Data) -> jsone:encode([{<<"data">>, lists:reverse(Data)}]);
set_json_from_sql(Columns, [H], Data) ->
NewData = set_json_merge(H, Columns, Data),
set_json_from_sql([], [], NewData);
set_json_from_sql(Columns, [H|T], Data) ->
NewData = set_json_merge(H, Columns, Data),
set_json_from_sql(Columns, T, NewData).
set_json_merge(Row, Columns, Data) ->
TupleRow = json_by_type(tuple_to_list(Row), Columns, []),
lists:append([TupleRow], Data).
所以 set_json_from_sql/3 在匹配 set_json_from_sql([], [], Data) 后会为您提供 Json 输出。
这里的关键点是您需要为字符串和原子调用list_to_binary/1。使用jsone将Erlang对象编码为Json:https://github.com/sile/jsone
并且,注意format_by_type/1 用于匹配 Erlang 对象类型,是的,并不理想,但只要您知道数据库的类型,或者您可以增加额外的防护来适应这种情况,它就可以工作。