Mac OS X 上 Ruby 连接 SQL Server

首先需要安装 FreeTDS,参考页面:FreeTDS 安装

安装配置 unixODBC

unixODBC 是在非 Windows 系统上广泛应用的一个 ODBC API 实现。

  1. 从官方网站下载、解压 unixODBC 并进入解压后的目录
  2. 运行如下命令安装:
    1. ./configure --enable-gui=no --prefix=/usr/local/unixODBC
    2. make
    3. sudo make install

这样 unixODBC 被安装到目录 /usr/local/unixODBC,该目录下的 bin 子目录有 isql 程序可供测试用,etc 子目录里是配置文件

sudo vim etc/odbc.ini,添加如下内容

[datasourcename]
Driver          = /usr/local/freetds/lib/libtdsodbc.so
Servername      = servername
Database        = Default_DB

datasourcename 是自己决定的名字,将来写 Ruby 程序的时候通过它来引用。servername 是在 "FreeTDS 安装" 一文中介绍的 freetds.conf 文件中配置好的。另外还可以指定一个默认的数据库(程序中随时可以通过 use some_database 来换数据库,也可以用 some_database.dbo.table_name 的全称引用)。

安装必要的 rubygems

sudo gem install dbi dbd-odbc

安装 ruby-odbc

ruby-odbc 可以通过 gem 安装,但是因为 Mac 上还有 iodbc,不能确定它会针对哪个编译。我们应该让它针对刚刚安装的 unixODBC 去编译。

  1. rubyodbc 官方网站 下载解压 ruby-odbc,并进入解压后目录
  2. 用如下命令编译安装:
    1. env ARCHFLAGS="-arch x86_64" ruby -Cext extconf.rb --with-odbc-dir=/usr/local/unixODBC
    2. make -C ext
    3. sudo make -C ext install

上面的 ARCHFLAGS 必须指定 x86_64, 否则 ruby-odbc 还是会去找 iODBC. 不指定的话,在 ext 目录生成的 Makefile 有如下的区别(四行):

47c47
< CFLAGS   =  -fno-common -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE  -fno-common  -pipe -fno-common $(cflags) 
---
> CFLAGS   =  -fno-common -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE  -fno-common  -pipe -fno-common $(cflags) 
52c52
< ldflags  = -L. -arch i386 -arch x86_64 
---
> ldflags  = -L. -arch x86_64 
56c56
< LDSHARED = cc -arch i386 -arch x86_64 -pipe -bundle -undefined dynamic_lookup
---
> LDSHARED = cc -arch x86_64 -pipe -bundle -undefined dynamic_lookup
89c89
< LIBS = $(LIBRUBYARG_SHARED) -liodbcinst -liodbc  -lpthread -ldl  
---
> LIBS = $(LIBRUBYARG_SHARED) -lodbcinst -lodbc  -lpthread -ldl

测试 Ruby 连接 SQL Server

写一小段 ruby 程序:

require 'rubygems'
require 'dbi'

dbh = DBI.connect("DBI:ODBC:datasourcename", 'user', 'password')
row = dbh.select_one("select top 1 * from ...")
puts row['column_name']

为什么不用 iODBC

ODBC Driver 除了前面提到的 unixODBC 之外还有一种选择 - Mac 自带的 iODBC。以前在 Mac OS X 10.5 (Leopard) 上,我用 iODBC 即可让 Ruby 成功连接 SQL Server。但是到了 10.6 (Snow Leopard),好景不再,iodbctest 测试没有问题,但是用 Ruby 连接就会出现这样的错误:

/Library/Ruby/Gems/1.8/gems/dbd-odbc-0.2.5/lib/dbd/odbc/statement.rb:41: [BUG] Segmentation fault
ruby 1.8.7 (2009-06-08 patchlevel 173) [universal-darwin10.0]

Abort trap

[iODBC 官方下载页] 提供了给 Snow Leopard 的 patch,但是我试了试情况更糟,iodbctest 都不行了,没有进行更多的尝试。