Erlang ODBC 处理中文
还是用官方的ODBC踏实,而且换什么数据库都不用改代码,方便。
测试的数据库:MYSQL,Oracle
MySql字符集:
SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
Oracle字符集:
SQL> select * from v$nls_parameters;
+-----------------------------------------------------------------+-----------------------------------------------------------------+
| PARAMETER | VALUE |
+-----------------------------------------------------------------+-----------------------------------------------------------------+
| NLS_LANGUAGE | AMERICAN |
| NLS_TERRITORY | AMERICA |
| NLS_CURRENCY | $ |
| NLS_ISO_CURRENCY | AMERICA |
| NLS_NUMERIC_CHARACTERS | ., |
| NLS_CALENDAR | GREGORIAN |
| NLS_DATE_FORMAT | DD-MON-RR |
| NLS_DATE_LANGUAGE | AMERICAN |
| NLS_CHARACTERSET | AL32UTF8 |
| NLS_SORT | BINARY |
| NLS_TIME_FORMAT | HH.MI.SSXFF AM |
| NLS_TIMESTAMP_FORMAT | DD-MON-RR HH.MI.SSXFF AM |
| NLS_TIME_TZ_FORMAT | HH.MI.SSXFF AM TZR |
| NLS_TIMESTAMP_TZ_FORMAT | DD-MON-RR HH.MI.SSXFF AM TZR |
| NLS_DUAL_CURRENCY | $ |
| NLS_NCHAR_CHARACTERSET | AL16UTF16 |
| NLS_COMP | BINARY |
| NLS_LENGTH_SEMANTICS | BYTE |
| NLS_NCHAR_CONV_EXCP | FALSE |
+-----------------------------------------------------------------+-----------------------------------------------------------------+
测试的数据库表:
mysql:
CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`f1` varchar(45) DEFAULT NULL
);
oracle:
create t1( "ID" NUMBER NOT NULL ENABLE, "F1" VARCHAR2(45 CHAR));
1、连接数据库
odbc:connect("DSN=test", [{scrollable_cursors, off}, {binary_strings, on}])
注意,打开binary_strings,不打开应该也可以,但下面的测试代码需要做相应的修改。
2、代码源文件格式
%% -*- coding: utf-8 -*-
3、插入中文字段
3.1、使用odbc:sql_query(这个我没测试过)
方法一:直接写中文
odbc:sql_query(DB, "INSERT INTO t1(f1) VALUES('马天才');")
ODBC返回出错如下:
=ERROR REPORT==== 6-Aug-2013::16:29:09 ===
** Generic server <0.47.0> terminating
** Last message in was {<0.46.0>,
{sql_query,[6,
[73,78,83,69,82,84,32,73,78,84,79,32,116,
49,40,102,49,41,32,86,65,76,85,69,83,40,
39,39532,22825,25165,39,41,59]]},
infinity}
** When Server state == {state,#Port<0.758>,undefined,<0.46.0>,undefined,on,
false,false,off,connected,undefined,0,
[#Port<0.756>,#Port<0.757>],
#Port<0.759>,#Port<0.760>}
** Reason for termination ==
** {{badmatch,{error,einval}},
[{odbc,odbc_send,2,[{file,"odbc.erl"},{line,832}]},
{odbc,handle_msg,3,[{file,"odbc.erl"},{line,557}]},
{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,588}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}
看到39532,22825,25165这三个数字了吗?这是"马天才“这三个字的codepoints,应该就是这个原因。
方法二,转为utf8试试
F = <<"马天才"/utf8>>, %% <<233,169,172,229,164,169,230,137,141>>
Sql = lists:flatten(io_lib:format("INSERT INTO t1(f1) VALUES('~s');", [F])),
odbc:sql_query(DB, Sql)
这次插入是成功啦,但插入到数据库中是乱码。
方法三,转为utf16(为什么要用utf16呢?有病乱投医)
F = <<"马天才"/utf16-little>>, %% <<108,154,41,89,77,98>>
Sql = lists:flatten(io_lib:format("INSERT INTO t1(f1) VALUES('~s');", [F])),
odbc:sql_query(DB, Sql)
这次插入也成功啦,但select返回时是<<108,0,154,0,41,0,89,0,77,0,98,0>>,为什么加一个0呀
3.2 用odbc:param_query(这个测试是OK的)
方法一:代码里直接中文
D = <<"马天才"/utf16-little>>, %% 中文必须要转为utf16-little
odbc:param_query(DB, "INSERT INTO t1(f1) VALUES(?);", [{{sql_wvarchar, 45}, [D]}])
注意:1. 中文要用utf16-little,为什么?
看这里
http://www.erlang.org/doc/apps/odbc/databases.html#id61509
方法二:程序收到的utf8
U = <<233,169,172,229,164,169,230,137,141>>, %% 这是utf8的"马天才“三个字
D = unicode:characters_to_binary(U, utf8, {utf16, little}), %% 转换为utf16-little
odbc:param_query(DB, "INSERT INTO t1(f1) VALUES(?);", [{{sql_wvarchar, 45}, [D]}])
4、查询中文字段
odbc:sql_query(DB, "select * from t1;")
4.1 在mysql里返回正常
4.2 在oracle里有点问题
odbc:describe_table(DB, "t1")
[{"id",sql_integer},{"f1",{sql_wvarchar,45}}]
oracle中如果varchar2为byte,则是这样:
[{"ID",{sql_float,38}},{"F1",{sql_varchar,45}}]
如果改为char,则是这样:
[{"ID",{sql_float,38}},{"F1",{sql_wvarchar,45}}]
也就是说,如果oracle中varchar2为byte,则erlang会认为它是sql_varchar类型,返回的结果不会转换。
Erlang ODBC 处理中文的更多相关文章
- 解决使用C/C++配置ODBC链接中文显示为问号(?)的问题
使用VS2015中使用OBDC连接到数据库时,数据库可以正常显示,但是在VS上输出是乱码,如图: 在数据库中course表显示: vs程序结果显示: 查找原因,因为char默认读ascii型,只读到1 ...
- oracle配置ODBC
摘自:http://www.cnblogs.com/shelvenn/p/3799849.html 我使用的Windows 10,64位的操作系统. 1.下载驱动包 base包:instantclie ...
- Erlang学习记录:相关工具和文档
在线工具和文档 网址 说明 OTP Reference Page Index 内置模块查询 Erlang/OTP Applications N Kernel Reference Manual 入门官方 ...
- MYSQL与 R
1. 配置MySQL ODBC必须先安装MySQL ODBC driver下载地址可以为:http://www.mysql.com/downloads/connector/odbc/ 2. 控制面板\ ...
- Lotus Domino开发心得(一)
—- Lotus Domino 是当今办公自动化系统的主流开发平台之一,目前大部分企业和机构都在使用Lotus Domino 开发自己的无纸办公系统.在开发过程中,我积累了一些小技巧,现在公布出来,希 ...
- Syncthing源码解析 - 启动过程
我相信很多朋友会认为启动就是双击一下Syncthing程序图标,随后就启动完毕了!如果这样认为,对,也不对!对,是因为的确是这样操作,启动了Syncthing:不对是因为在调试Syncthing启动过 ...
- 如何正确设置 Informix GLS 及 CSDK 语言环境
本文介绍 GLS 相关知识,说明如何正确设置 Informix GLS 语言环境相关变量(DB_LOCALE,CLIENT_LOCALE),保证 Informix 数据库服务器.客户端能正确的支持中文 ...
- erlang转化中文为url
今天使用http get 方法时,参量中有中文而导致出错. 例如http://abc.com/abc?arg=中文,在erlang使用http:request方法失败. 后来查了url的规范,url中 ...
- 解决erlang R17无法识别中文问题
erlang更新到R17已有一段时间了.公司项目打算从旧版的erlang迁移到R17,却不料有不少的困扰,当中一个问题是中文问题. 这个问题非常easy重现:新建一个文件t.erl.保存为utf-8无 ...
随机推荐
- (转)最近研究xcodebuild批量打包的一些心得
以前的时候只知道做安卓开发的兄弟挺辛苦的,不但开发的时候要适配一堆的机型,好不容易开发完了还要打一堆不同的包给不同的市场.没想到现在这些市场都开辟iOS市场,于是需要打一堆的包给不同的市场,面对暂时给 ...
- setNeedsDisplay setNeedsLayout
setNeedsDisplay调用drawRect方法来实现view的绘制,而setNeedsLayout则调用layoutSubView来实现view中subView的重新布局 转自 http:/ ...
- mysql简单练习
数据库入门 2.1 引入 数据保存到内存: 优点: 1)读写非常快 缺点: 1)程序关闭导致数据丢失 数据保存到文件: 优点: 1)数据可以永久保存 缺点: 1)频繁地IO操作,效率不高! 2)数据管 ...
- event.getAction()&MotionEvent.ACTION_MASK的原因
看到下面代码中用了AND位运算是为了什么呢? public boolean onTouchEvent(MotionEvent event) { int action = event.getAction ...
- ls 命令详解
1.ls基本语法及选项 用法:ls [选项]... [文件]... List information about the FILEs (the current directory by default ...
- 根据id查询数据(向前台返回json格式的数据)
/** *@description 根据主键查询Bean */ @RequestMapping(value="/getBean/{getId}") public void getB ...
- iframe 元素
iframe 元素会创建包含另外一个文档的内联框架(即行内框架). 可以访问:http://www.w3school.com.cn/tags/tag_iframe.asp
- Sass函数--数字函数
数字函数简介 Sass 中的数字函数提要针对数字方面提供一系列的函数功能: percentage($value):将一个不带单位的数转换成百分比值: round($value):将数值四舍五入,转换成 ...
- html 使用表单标签,与用户交互
使用表单标签,与用户交互 网站怎样与用户进行交互?答案是使用HTML表单(form).表单是可以把浏览者输入的数据传送到服务器端,这样服务器端程序就可以处理表单传过来的数据. 语法: <form ...
- GridView格式化数据DataFormatString
设定BoundField的DataFormatString,通常有以下几种 DataFormatString= "{0:C}" 货币,货币的格式取决于当前Thread中Cultur ...