从PostgreSQL Erlang获取unicode数据

从PostgreSQL Erlang获取unicode数据,postgresql,unicode,erlang,ejabberd,Postgresql,Unicode,Erlang,Ejabberd,我正在尝试使用Erlang从PostgreSQL获取数据。 这是我从数据库中获取数据的代码。然而,我在“状态”列中有西里尔字母数据。未正确获取此cyrrilic数据。 我试过使用UserInfo=io_lib:format(“~tp~n”,[UserInfoQuery]),但是这似乎不起作用,因为它会使应用程序崩溃 UserInfoQuery = odbc_queries:get_user_info(LServer,LUser), UserInfo = io_lib:format("~p",[U

我正在尝试使用Erlang从PostgreSQL获取数据。 这是我从数据库中获取数据的代码。然而,我在“状态”列中有西里尔字母数据。未正确获取此cyrrilic数据。 我试过使用
UserInfo=io_lib:format(“~tp~n”,[UserInfoQuery]),
但是这似乎不起作用,因为它会使应用程序崩溃

UserInfoQuery = odbc_queries:get_user_info(LServer,LUser),
UserInfo = io_lib:format("~p",[UserInfoQuery]),
?DEBUG("UserInfo: ~p",[UserInfo]),
StringForUserInfo = lists:flatten(UserInfo),

get_user_info(LServer, Id) ->
ejabberd_odbc:sql_query(
  LServer,
  [<<"select * from users "
     "where email_hash='">>, Id, "';"]).
错误:

bad argument in call to erlang:iolist_size([123,60,60,34,97,100,109,105,110,34,
62,62,44,60,60,34,97,100,109,105,110,34,62,62,44,60,60,34,50,...])

我不明白为什么
io:format(“~tp”)
不起作用,但您可以提取所需的行和列,并使用
io:format(~ts”)
打印它们:


我不明白为什么
io:format(“~tp”)
不起作用,但您可以提取所需的行和列,并使用
io:format(~ts”)
打印它们:


我不明白为什么
io:format(“~tp”)
不起作用,但您可以提取所需的行和列,并使用
io:format(~ts”)
打印它们:


我不明白为什么
io:format(“~tp”)
不起作用,但您可以提取所需的行和列,并使用
io:format(~ts”)
打印它们:


Erlang ODBC驱动程序完美地从数据库中获取了状态列。事实上,PostgreSQL将您的数据编码为UTF-8,而您得到的值是UTF-8编码的

Status = <<209,139,209,132,208,178,208,176,209,139,209,132,208,178,208,176>>.
它将输出两个字符,00D1(带波浪号的拉丁文大写字母N)和008B(部分向前行)。这是因为它被解释为拉丁语-1字符串,而不是UTF-8编码字符串

以下行将失败:

io:format("~s", [[1099]]).
这是因为[1099]不是有效的拉丁语-1字符串

相反,你应该写:

io:format("~ts", [<<209,139>>]),
io:format("~ts", [[1099]]).
实际上,
t
修饰符仅表示参数应接受unicode输入。如果您确实使用
~p
,在格式化字符串或二进制文件时,Erlang将确定是否可以将其表示为拉丁-1字符串,因为输入可能是拉丁-1编码的。这种启发式方法允许Erlang在大多数情况下正确区分整数和字符串列表。要了解启发的作用,您可以尝试以下方法:

io:format("~p\n~p\n", [[69,114,108,97,110,103], [1,2,3,4,5,6]]).
启发式算法检测到
[69114108,97110103]
实际上是
“Erlang”
,而
[1,2,3,4,5,6]
只是一个整数列表

如果您确实使用
~tp
,Erlang将希望字符串或二进制文件采用unicode编码,然后应用默认的识别启发。目前默认的启发式(R17)也是拉丁语-1。因为您的字符串不能用拉丁语-1表示,所以Erlang将它显示为整数列表。幸运的是,通过在命令行上将
+pcunicode
传递给Erlang,您可以切换到Unicode启发式,这将产生您想要的结果

$ erl +pc unicode

因此,问题的解决方案是传递
+pcunicode
,并使用
~tp

Erlang ODBC驱动程序从数据库中完美地获取状态列。事实上,PostgreSQL将您的数据编码为UTF-8,而您得到的值是UTF-8编码的

Status = <<209,139,209,132,208,178,208,176,209,139,209,132,208,178,208,176>>.
它将输出两个字符,00D1(带波浪号的拉丁文大写字母N)和008B(部分向前行)。这是因为它被解释为拉丁语-1字符串,而不是UTF-8编码字符串

以下行将失败:

io:format("~s", [[1099]]).
这是因为[1099]不是有效的拉丁语-1字符串

相反,你应该写:

io:format("~ts", [<<209,139>>]),
io:format("~ts", [[1099]]).
实际上,
t
修饰符仅表示参数应接受unicode输入。如果您确实使用
~p
,在格式化字符串或二进制文件时,Erlang将确定是否可以将其表示为拉丁-1字符串,因为输入可能是拉丁-1编码的。这种启发式方法允许Erlang在大多数情况下正确区分整数和字符串列表。要了解启发的作用,您可以尝试以下方法:

io:format("~p\n~p\n", [[69,114,108,97,110,103], [1,2,3,4,5,6]]).
启发式算法检测到
[69114108,97110103]
实际上是
“Erlang”
,而
[1,2,3,4,5,6]
只是一个整数列表

如果您确实使用
~tp
,Erlang将希望字符串或二进制文件采用unicode编码,然后应用默认的识别启发。目前默认的启发式(R17)也是拉丁语-1。因为您的字符串不能用拉丁语-1表示,所以Erlang将它显示为整数列表。幸运的是,通过在命令行上将
+pcunicode
传递给Erlang,您可以切换到Unicode启发式,这将产生您想要的结果

$ erl +pc unicode

因此,问题的解决方案是传递
+pcunicode
,并使用
~tp

Erlang ODBC驱动程序从数据库中完美地获取状态列。事实上,PostgreSQL将您的数据编码为UTF-8,而您得到的值是UTF-8编码的

Status = <<209,139,209,132,208,178,208,176,209,139,209,132,208,178,208,176>>.
它将输出两个字符,00D1(带波浪号的拉丁文大写字母N)和008B(部分向前行)。这是因为它被解释为拉丁语-1字符串,而不是UTF-8编码字符串

以下行将失败:

io:format("~s", [[1099]]).
这是因为[1099]不是有效的拉丁语-1字符串

相反,你应该写:

io:format("~ts", [<<209,139>>]),
io:format("~ts", [[1099]]).
实际上,
t
修饰符仅表示参数应接受unicode输入。如果您确实使用
~p
,在格式化字符串或二进制文件时,Erlang将确定是否可以将其表示为拉丁-1字符串,因为输入可能是拉丁-1编码的。这种启发式方法允许Erlang在大多数情况下正确区分整数和字符串列表。要了解启发的作用,您可以尝试以下方法:

io:format("~p\n~p\n", [[69,114,108,97,110,103], [1,2,3,4,5,6]]).
启发式算法检测到
[69114108,97110103]
实际上是
“Erlang”
,而
[1,2,3,4,5,6]
只是一个整数列表

如果您确实使用
~tp
,Erlang将希望字符串或二进制文件采用unicode编码,然后应用默认的识别启发。目前默认的启发式(R17)也是拉丁语-1。因为您的字符串不能用拉丁语-1表示,所以Erlang将它显示为整数列表。幸运的是,您可以切换到Unicode启发式