LinuxからSQL ServerにODBCで接続する

## はじめに
PHPでMSSQL関数に繋いでデータを取得するのは前回に説明しました。
しかし、検索を掛ける限りODBCで接続することが多いようです。
今度はLinuxからSQL ServerにODBCで接続する方法を説明します。
この回では、isqlにて接続確認を行うところまで説明します。

## 接続イメージ

```
ODBC関数(PHP,Perl,Ruby等) <-> unixODBC <-> FreeTDS <-> SQL Server
```
LinuxからODBCでSQL Serverに接続する設定は、PHPでもPerlでもRubyでも、
isqlで接続確認するまでの過程は全く変わりません。PerlやRuby、Python等で接続される方も参考になるかと思います。

### 環境
#### ホスト
* SQL Server 2008R2 Express
* WindowsXP

#### クライアント
* Ubuntu 12.04.3LTS

# ライブラリーをインストール
#### unixodbc
* unixODBC
* ODBCドライバーを扱うためのドライバーマネージャー

#### tdsodbc
* FreeTDSのODBC接続API

#### freetds-common
* FreeTDS
* SQL ServerやSybaseへ接続するためのプロトコル

上記のドライバを下記のようにインストールします。

```shell-session:ドライバーインストール
$ sudo apt-get install freetds-common tdsodbc unixodbc
```

必要なライブラリやソフトはインストールできました。
次は設定を行っていきます。

# DSN-Onlyという方法を説明
[Preparting ODBC](http://www.freetds.org/userguide/prepodbc.html)によると、
LinuxからODBCへ接続する方法は3種類ある。

### DSN-less
* odbc.iniもfreetds.confも使わずに接続する方法。
* ソースに接続文字列を書いて接続します。

### DSN-Only
* odbc.iniの設定だけで接続する方法。
         
### DSN-Combine
* odbc.iniとfreetds.confの設定を使う。
* freetds.confはDSNの設定のservernameの項目で使われる。

DSN-lessの接続は私の設定では巧くいかなかった。
DSN-OnlyとDSN-Combineについては成功した。
今回は **DSN Onlyで接続する方法** を説明する。

# ODBCINSTで設定
unixodbcでdriverやDataSource Name(DSN)等の設定は、iniファイルに設定ファイルを書くか、
odbcinstというツールを使って設定します。
ここではodbcinstを使った設定を説明します。


## unixODBCにODBC用のFreeTDSドライバーを登録

### ODBCドライバーの場所の特定
FreeTDSのODBCドライバーの場所を特定します。
下記のようにコマンドを実行して探し出します。

```shell-session:場所の特定
$ sudo updatedb
$ locate tdsodbc
/usr/lib/i386-linux-gnu/odbc/libtdsodbc.so
....(省略)...
```
**libtdsodbc.so**がインストールしたFreeTDSのODBCドライバーを表しています。
/usr/lib/i386-linux-gnu/odbc　のフォルダの中には
**libtdsS.so**　があります。
これはセットアップファイルです。

```shell-session
$ ls /usr/lib/i386-linux-gun/odbc/*tdsS*
/usr/lib/i386-linux-gnu/odbc/libtdsS.so
```

以下の2つのPathを覚えておきましょう。
#### ODBCドライバーの場所
/usr/lib/i386-linux-gnu/odbc/libtdsodbc.so

#### ドライバーのセットアップファイルの場所
/usr/lib/i386-linux-gnu/odbc/libtdsS.so

### ドライバーテンプレートファイルの作成
下記のようにテンプレートファイルを作ります。

```shell-session
$ vi driver.template
[FreeTDS]
#ドライバーの説明
Description =  FreeTDS for SQL Server   
#ODBCドライバーの場所
Driver = /usr/lib/i386-linux-gnu/odbc/libtdsodbc.so
#ドライバーのセットアップファイルの場所     
Setup = /usr/lib/i386-linux-gnu/odbc/libtdsS.so
```    

### ドライバーのインストール
下記のように実行します。

	$sudo odbcinst -i -d -f driver.templat


* -i インストール
* -d ドライバー
* -f テンプレートファイル名 

ODBCドライバーのインストールは **root権限** で行って下さい。root権限以外で実行すると下記のようなエラーが出てインストールできません。

	odbcinst: SQLInstallDriverEx failed with Invalid install path.

### ドライバーのアンインストール
ドライバーをアンインストールするには下記のように行います。

ドライバー名を確認

	$ odbcinst -q -d
	[FreeTDS]


* -q 検索 
* -d ドライバー

ドライバーアンインストール

	$ sudo odbcinst -u -d -n DriverName

* -u アンインストール
* -n ドライバー又はDSN名

## データソースの設定
以下の条件でデータソースを登録します。
 
### ホスト
- SQL Server 2008 R2
- 文字コード: CP932
- IP: 192.168.0.3
- DB username:  sa
- DB password password

### クライアント
- Ubuntu 12.03
- 文字コード:　UTF-8

上記の条件を元にデータソーステンプレートを作成します。

### データソーステンプレートの作成
```shell-session:データソーステンプレート
    $ vi dsn.template
    [2008R2]
	#ドライバーの説明
    Description = SQL Server2008R2
    #ドライバーの場所　
    #  ドライバーのフルパスか
    #  ドライバー名(ここではFreeTDS)を記述する
    Driver = /usr/lib/i386-linux-gnu/odbc/libtdsodbc.so
    #トレースするかの有無
    Trace = No
	#データベースのIPアドレス
    Server = 192.168.0.3
	#データベース名
    Database = arakawa
	#ポート番号 SQL Serverは通常 1433
    Port = 1433
	#TDS_Version SQLServer2000は7.1 SQLServer2005以降は7.2
    TDS_Version = 7.2
	#クライアント(Linux側)の文字コードセット
    ClientCharset = UTF-8
```

### データソースのインストール
データソースを設定したテンプレートのある場所で、
下記のようなコマンドでインストールします。

	$ sudo odbcinst -i -s -l -f dsn.template

*  -i インストール
*  -s DSN（データソース名)
*  -l system dsn
*  -f テンプレートのファイル名

下記のようにユーザー権限でインストールしてしまうと、
/home/users/.odbc.ini
にDSN名が書き込まれてしまう。

	$ odbcinst -i -s -f dsn.template
	$ cat /home/users/.odbc.ini
	[2008R2]
	Description = ODBC Driver for SQL Server2008R2
	......

ApacheのようなWebserverはSystem Datasource(system dsn)しか使いません。
なので、 **ルート権限** で **system dsn** を登録する必要があります。

下記サイトのSystem versus Userを参照

[unixODBC without GUI](http://www.unixodbc.org/odbcinst.html)

### データソースのアンインストール
データソースをアンインストールする場合は下記のように行います。

データソース名を検索

	$ odbcinst -q -s
	[2008R2]

データソースを削除

	$ odbcinst -u -s -n 2008R2


# データベース接続確認
これで、isqlで接続できるか確認します。

下記のように接続します。

    $isql -v 2008R2 sa password
    +---------------------------------------+
    | Connected!
    |   
    | sql-statement 
    | help [tablename]  
    | quit 
    |   
    +---------------------------------------+
    SQL>


試しに以下のようなSQLを実行してみましょう

```shell-session
SQL>Select @@version

--------------------------------------------------------------+
| Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (Intel X86)
        Jun 28 2012 08:42:37
        Copyright (c) Microsoft Corporation
        Express Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)

                           |
+--------------------------------------------------------------+
SQLRowCount returns 1
1 rows fetched
```
サーバーのバージョンが出てきました。
成功です。


日本語文字列が文字化けするかも調査してみます。

```sql:データベース作成
SQL>CREATE DATABASE 日本語テーブル達
SQLRowCount returns -1
```

```sql:使用するDBを変更
SQL> use 日本語テーブル達
[01000][unixODBC][FreeTDS][SQL Server]Changed database context to '日本語テーブ
ル達'.
[ISQL]INFO: SQLExecute returned SQL_SUCCESS_WITH_INFO
SQLRowCount returns -1
```

```sql:テーブル作成
SQL> create table 名前リスト(ID int IDENTITY(1,1) PRIMARY KEY,名前 nvarchar(40))
SQLRowCount returns -1
```

```sql:データ挿入
SQL> insert into 名前リスト(名前) values('織田 信長')
SQLRowCount returns 1
```

```sql:データ表示
SQL> select * from 名前リスト
+------------+-----------------------------------------+
| ID         | 名前                                  |
+------------+-----------------------------------------+
| 1          | 織田 信長                           |
+------------+-----------------------------------------+
SQLRowCount returns 1
1 rows fetched
SQL>
```
文字化けしていなければ問題なし。

後は、PHPやPerl,Ruby,Python等のODBCドライバーで接続の設定をしていきましょう。
私はPHPを使いますのでPHPの設定を説明します。

下記urlで見て下さい。

[Linux PHPからODBCでSQL Serverに接続](http://qiita.com/arachan@github/items/aad9a0b74607f5e6e608)
[Linux PerlからODBCでSQL Serverに接続](http://qiita.com/arachan@github/items/34cedba6a60accf87b10)