F# で Oracle にアクセスしてみたよ!

<はじめに>
この記事は F# Advent Calendar 2013 7日目の記事です。

6日目は@masaru_b_clさんの F# InteractiveをConEmu上で利用する でした。

さて、F#を勉強し始めて、プライベートでちょいちょい書いていると、

「そのうち業務でもF#使いたいなー?」なんて妄想したりしますよね?

いざF#を業務に導入するとなると、

きっと既存の情報資産を活用できて、かつインパクトが少ない

例えば小規模なマスタメンテ用のWebサービスの作成ぐらいから

始めていくのが現実的かなー?なんて思ったりします。

今回はそんな来るべき日に備えて、

ADO.NETを使ってF#でOracleにアクセスする方法」

を覚書程度に書いてみました。

<対象データ>
下記のテーブルからデータを取得します。

f:id:nomurabbit:20131201223313p:plain

<プログラム1>
とりあえず、コンソールアプリケーションで単純にOracleからデータを取得してみます。

OracleClientはOracle.DataAccess.Clientを利用します。

open System
open System.Data
open System.Configuration
open Oracle.DataAccess.Client

[<EntryPoint>]
let main(args : string[]) = 

    // 接続文字列の取得
    let conStr = ConfigurationManager.ConnectionStrings.Item "connection"
    let con    = new OracleConnection(conStr.ToString())
    
    // SQLの定義
    let sqlStr = "SELECT * FROM MEMBER WHERE ID = 1"
    let cmd    = new OracleCommand(sqlStr, con)

    con.Open()

    // データの取得
    let reader = cmd.ExecuteReader()
    let result = reader.Read()
    
    // 取得したデータの出力
    printfn "%s %s %s %s" (reader.GetString(0)) (reader.GetString(1)) (reader.GetString(2)) (reader.GetString(3))
    
    reader.Close()
    con.Close()
    
    0

ちなみに接続文字列はApp.configから取得しています。

中身はこんな感じです。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="connection" connectionString="Data Source=XE;User ID=hoge;Password=fuga;"></add>
  </connectionStrings>
</configuration>

<実行結果1>
f:id:nomurabbit:20131201223320p:plain

上手くデータが取得できました!

<プログラム2>
目標はマスタメンテ用のWebサービスを作ることなので、

次はWebサービスを作ってみることにします。

open System
open System.IO
open System.Data
open System.Configuration
open Oracle.DataAccess.Client
open FSharpWcfServiceApplicationTemplate.Contracts

type Service1() =
    interface IService1 with
        member x.GetOracle value =

            // 接続文字列の取得
            let conStr = ConfigurationManager.ConnectionStrings.Item "string1"
            let con    = new OracleConnection(conStr.ToString())
            
            // SQLの定義
            let sqlStr = "SELECT * FROM MEMBER WHERE ID = " + value
            let cmd    = new OracleCommand(sqlStr, con)
            
            con.Open()
            
            // データの取得
            let reader = cmd.ExecuteReader()
            try
                try
                    let a = reader.Read()
                    sprintf "%s %s %s %s" (reader.GetString(0)) (reader.GetString(1)) (reader.GetString(2)) (reader.GetString(3))
                with
                    | :? FormatException as e ->
                        e.Message
                    | :? IOException as e ->
                        e.ToString()
                    | _  as e->
                        "???"
            finally
                reader.Close()
                con.Close()

<実行結果2>
デバッグで引数に"2"を渡して実行してみた結果がこちら。

f:id:nomurabbit:20131201224856p:plain

こちらも上手く値が返ってきました。

<プログラム3>
それでは最後に、C#で書かれた適当なクライアントから

先ほど作ったWebサービスをサービス参照で呼び出してみます。

public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    var webService = new FSservice.Service1Client();

    this.textBox1.Text = webService.GetOracle("3");
}

<実行結果3>
f:id:nomurabbit:20131201230943p:plain

おー!値が取得できました!

<まとめ>
F#を使って(というかADO.NETを使って)Oracleにアクセスすることができました。

取得したデータをF#でいかに扱うかを勉強していきたいと思います。

F# AdventCalender 2013 7日目は以上です。

明日は@n_enotさんの「F# で System.Reflection(仮)」です。