在Linux下使用odbc包连接MSSQL Server

栏目: 数据库 · SQL Server · 发布时间: 6年前

内容简介:在《忍无可忍的Encoding》一文中提到:举个栗子:

在《忍无可忍的Encoding》一文中提到:

RSQLServer包 退役了,作者建议使用 r-dbi/odbc包 代替。但是,odbc包并没有像RODBC包一样(版本1.1.6已经修复这个问题), 预先把 SQL 字符编码转换成和数据库一致的字符编码 ,导致无法正确执行包含中文的SQL语句(如果该语句的字符编码和数据库的编码不一致)。

举个栗子:

  1. MSSQL Server数据库:一般放在某个中文Windows Server服务器上,大概率其数据库默认字符编码是GB2312;
  2. 客户端:使用某个中文的Windows(默认字符编码也是GB2312);
  3. 建立一个使用odbc包的数据库链接 conn ,执行下列语句:

    sql_native <- "select * from tbl where field_a = '中文'"
    sql_utf8 <- enc2utf8(sql_native)
    DBI::dbGetQuery(conn, sql_native)
    # 会有数据
    DBI::dbGetQuery(conn, sql_utf8)
    # 要么报错要么返回一个空的数据集

我提交了这个八阿哥的报告 r-dbi/odbc#179 ,作者 Jim Hester 也很快地解决了这个问题,测试了下没问题,一切看起来似乎很美好。

今天正好有空,决定正式把所有和RSQLServer相关的数据链接都使用odbc替换掉(只需要把负责数据库连接的包进行修改,然后重新测试部署即可)。Windows上一切正常,但是在 Linux 中又遇到了问题 —— 只要是包含中文的SQL都会报错: Invalid multibyte sequence

鼓捣了一会儿后意识到,在Linux下使用的是FreeTDS驱动(unixODBC只是一个驱动管理器,不同的数据库还需要装不同的驱动才行),但和微软的SQL Server驱动不同,FreeTDS默认会将返回的数据结果字符部分转换为UTF8编码,然而odbc包却假设数据库返回结果的编码和数据库编码一致,而且会在结果返回到R之前,试图将数据库编码转换为标准的UTF-8编码 —— 于是便导致了“试图将已经是UTF8编码的数据当做是GB2312重新转换为UTF8而报错”的问题(相信我,这句子多读几遍就能读顺 :smiley: )。

知道了病因,医生开药便简单了,简单搜索了下便知晓了FreeTDS可以在连接中设置 clientcharset 这个参数,配置成GB2312便可以保证其返回的数据结果和odbc包期待的结果一样啦。

简单总结下“在Linux下使用odbc包连接MSSQL Server”的注意事项:

  1. 安装unixODBC(驱动管理器)和FreeTDS(MSSQL Server驱动);

    apt-get install unixodbc unixodbc-dev tdsodbc
  2. 注册FreeTDS驱动,可参照 《Linux下连接MS Sql server – 使用ODBC/FreeTDS组合(详细)》 或者我的 Docker文件 ,总之就是让unixODBC知道你的Driver文件libtdsodbc.so在哪里;

    • 把下面的文本保存在任意地方,比如 /var/tds.driver.template ,注意Driver的地址可能未必和我的一致;

      [FreeTDS]
      Description = Free TDS
      Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
    • 然后执行下面的语句即可。

    odbcinst -i -d -f /var/tds.driver.template
  3. 按如下方式配置你的odbc链接。

    conn <- DBI::dbConnect(
      drv = odbc::odbc() ,
      server = "your ip",
      port = 1433, # FreeTDS必须要填端口号
      database = "your db",
      uid = "your user name",
      pwd = "your password",
      encoding = "GB2312", # 服务器编码-中文一般就是这个
      driver = "FreeTDS", # 和第二步你设置的名称一样就好
      clientcharset = "GB2312" # 必须要加这一个参数
    )

最后,想起益辉大人提到,写文章 “最重要的因素还是胸中是否有一股不吐不快的气” 。这股“不吐不快的气”我自己是时常都能感觉到的(我可是个吐槽大王啊),可惜经常没能及时将这股气幻化为文字,一拖便散了,不想写了。不过最近积攒的能量(:u6709:怨气:stuck_out_tongue_closed_eyes: )尤为多,且看能吐多少。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人类思维如何与互联网共同进化

人类思维如何与互联网共同进化

[美] 约翰·布罗克曼 / 付晓光 / 浙江人民出版社 / 2017-3 / 79.90元

➢人类是否因互联网的诞生进入了公平竞争的场域? “黑天鹅事件”频频发生,我们的预测能力是否正在退化? 智人的第四阶段有哪些特征? 全球脑会使人类成为“超级英雄”吗? 虚拟现实技术会不会灭绝人类的真实体验? 还有更多不可预知答案的问题,你将在本书中找到属于自己的答案! ➢ 我们的心智正和互联网发生着永无止境的共振,人类思维会因此产生怎样的进化效应?本书编者约翰•布......一起来看看 《人类思维如何与互联网共同进化》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具