Steadfast

仕事で
「C#で別サーバにあるPostgreSQLのDBにODBC経由で接続する」
というのをやろうとして、えらい悩む羽目になりました。
Oracleと比べて、.NetでpostgreSQLを使う例があまり見つからなかったので
忘れないようにメモ。

// 接続文字列
OdbcConnectionStringBuilder connStr = new OdbcConnectionStringBuilder();
connStr["DRIVER"] = "PostgreSQL Unicode";   // インストールしたODBCドライバ名
connStr["ENCODING"] = "UNICODE";              // エンコード
connStr["SERVER"] = "192.0.2.0";            // 接続先サーバのIPアドレスまたはホスト名
connStr["PORT"]   = "5432";                 // 接続先サーバのDBのポート。デフォルトは5432
connStr["DATABASE"] = "DBName";               // 接続先DBの名前
connStr["UID"]    = "UserName";             // PostgreSQLのユーザ名
connStr["PWD"]    = "PassWord";             // PostgreSQLのログインパスワード

OdbcConnection odbcConn = null;     // ODBC接続オブジェクト
OdbcCommand odbcCmnd = null;        // ODBCSQL実行オブジェクト
OdbcDataReader odbcRead = null;     // ODBCSQL実行結果取得オブジェクト

try
{
    // 接続
    odbcConn = new OdbcConnection(connStr.ConnectionString);
    odbcConn.Open();
    // 実行するSQLの設定
    odbcCmnd = new OdbcCommand();
    odbcCmnd.Connection = odbcConn;
    odbcCmnd.CommandText = "SELECT * FROM table;";
    // 実行後、読み取りオブジェクトを取得
    odbcRead = odbcCmnd.ExecuteReader();
    // 全部読み出す
    while (odbcRead.Read())
    {
        Console.WriteLine("Column1:" + odbcRead.GetString(0));
        Console.WriteLine("Column2:" + odbcRead.GetString(1));
    }
}
finally
{
    // 後始末
    if (odbcConn != null && odbcConn.State == ConnectionState.Open)
    {
        odbcConn.Close();
    }
    if (odbcRead != null && !odbcRead.IsClosed)
    {
        odbcRead.Close();
    }
}


接続文字列のDRIVERはインストールしたODBCドライバの名前を設定する。
psqlodbcをインストール後、
「コントロールパネル」→「管理ツール」→「データ ソース (ODBC)」→「システムDSN」タブ
でドライバを追加する。


接続文字列のDRIVERに設定するODBCドライバの名前は、32bitの場合は "PostgreSQL Unicode" または "PostgreSQL ANSI"、64bitの場合は "PostgreSQL Unicode(x64)" または "PostgreSQL ANSI(x64)"になる。
PostgreSQL35Wとかでいいのかと思ったらうまくいかなかった。


元々はこれをWindowsServer2008のIIS上のASP.NETで動かそうと思っていたんですが、「ドライバ、データソースが存在しない」みたいなメッセージが出て、すごい悩まされた。
原因は、IISのアプリケーションプールで「32ビットアプリケーションの有効化」を設定したためだった。
どうしても32bitのDLLを使用しなくてはいけなくてこの設定をしていたのだが、WindowsServerにインストールしていたpsqlodbcが64bitで、接続文字列のDRIVERに "PostgreSQL Unicode(x64)" を渡しても32bitのアプリケーションとして動いているので64bitのODBCドライバを認識できなかったようです。
32bitのpsqlodbcをインストールして、接続文字列のDRIVERを "PostgreSQL Unicode" にしたら無事動きました。
本当はWOW64にしないのがベストなんだろうけど・・・。

=================================
2012/11/6
接続文字列が間違っていたので修正。
× ENCODE → ○ ENCODING
× DBNAME → ○ DATABASE