すぐ使えるADO.NET

【Visual BasicによるADO.NETデータベースプログラミング】

本の紹介

バックナンバー:VB.NETデータベースプログラミング

ADO.NETの基本的なプログラミングを中心に、すぐ使えるサンプルプログラム満載です。




【第35号】

 第35号(2005.12.16発行)
======================================================================
           ★★ VB.NETデータベースプログラミング奮闘記 ★★
----------------------------------------------------------------------
いつもご購読ありがとうございます。今年最後の発行となりました。
来年もよろしくお願い申し上げます。

すぐ使えるADO.NET --> サンプルプログラム満載
                      http://park5.wakwak.com/‾weblab/
======================================================================
  ■■ VB.NETワンポイント:Try … Catch … Finally … End Try ■■

 Public Sub New() を修正します。前号までは、Tryブロック内で、
mConn.Openメソッドと、mConn.Closeメソッドを呼び出していましたが、
Closeメソッドを呼び出す前に、例外が発生すると、Catchブロックに制御が移
り、Closeメソッドが実行されなくなります。Closeメソッドを確実に実行する
ために、existKeyRecordメソッドやgetKeyRecordメソッドと同様に、Finally
ブロックにmConn.Closeメソッドを移動します。

--【修正前】----------------------------------------
 Public Sub New()

     Try
        ..........(省略)..........

        mConn.Open()

        ..........(省略)..........

        mConn.Close()

     Catch oExcept As Exception
        Throw New Exception _
        ("clsDBIOのコンストラクタで例外発生" + oExcept.ToString)

     End Try

 End Sub

--【修正後】----------------------------------------
 Public Sub New()

     Try
        ..........(省略)..........

        mConn.Open()

        ..........(省略)..........

     Catch oExcept As Exception
        Throw New Exception _
        ("clsDBIOのコンストラクタで例外発生" + oExcept.ToString)

     Finally
        'DB接続を閉じる
        If Not mConn Is Nothing Then
            If mConn.State = ConnectionState.Open Then
                mConn.Close()
            End If
        End If

     End Try

 End Sub

clsDBIOクラスのSub New()ソースリストを修正しました。ご迷惑をおかけして
申し訳ございません。

----------------------------------------------------------------------
     ■■ データベースアクセスクラスの汎用メソッドについて 4 ■■

1フィールドで主キーを構成するテーブルからキー値のレコードを取得するた
めに、今までは、各テーブル名に合わせて、getSyainのようにテーブル名を付
加したメソッドを作成してきましたが、今回は、テキスト型の1フィールドで
主キーを構成するテーブルからキー値のレコードを取得する汎用的な
getKeyRecordメソッドを作成します。

◆引数のNothing(未設定)チェック
引数が未設定の場合、myDBIOException例外をスローします。

◆テーブル名チェック
引数のテーブル名がmTableNameListになければ、エラーとして、
myDBIOException例外をスローします。

◆テーブルのキーフィールド名の取得
コネクションオブジェクトのGetOleDbSchemaTableメソッドを使って、キー
フィールド名を取得します。

  Dim schemaTable As DataTable = _
  mConn.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, _
  New Object() {Nothing, Nothing, parTableName})

◆キー値のチェック
キー値のチェックは、まず前後の空白を除去します。そして正規表現Regexク
ラスのIsMatchメソッドを使って、数字、英大文字、英小文字、"_"、"-"以外
の文字が含まれていれば、エラーとします。

◆SQL文の構築
parTableNameは引数の値を使い、keyFieldの値以外は、固定文字列を使って、
連結して生成します。

  Dim keyField As String
  Dim wherePhrase As String
  Dim oleDbPara As String

  keyField = schemaTable.Rows(0).Item(3).ToString
  wherePhrase = keyField + "= @key"

  mCommand.CommandText = _
  "SELECT * FROM " + parTableName + " WHERE " + wherePhrase

◆レコードの取得
データアダプタのFillメソッドを呼び出します。取得したレコードは
DataTable型になります。この型をgetKeyRecordメソッドを戻り値に指定すれ
ば、引数に指定したテーブルの主キー値のレコードを受け取ることができます。

なお、closeメソッドについては他のメソッドと同様に、Finallyブロックに
コーディングします。

次号では、主キーが複数フィールドから構成されているテーブルから引数に指
定したテーブルのキー値のレコード1行を取得する汎用的なメソッド
getKeyRecordメソッドをclsDBIOクラスに追加します。

--【プログラムソースリスト】------------------------------------------
Option Explicit On

Imports System.Data.OleDb
Imports System.Text.RegularExpressions

'----------------- << データベースアクセスクラス >> -----------------
Public Class clsDBIO

  '--------------------< メンバ:変数 >--------------------
  'コネクション
  Private mConn As OleDbConnection
  'コマンド
  Private mCommand As OleDbCommand
  'テーブル名コレクション
  Private mTableNameList As New Collection()

  '*******************************************************************
  ' 機能:コンストラクタ
  ' 引数:なし
  ' 履歴:2005.12.16 追加したFinallyブロックにmConn.Close()を移動
  '*******************************************************************
  Public Sub New()

    Try
      'DB接続文字列の設定
      mConn = New OleDbConnection()
      mConn.ConnectionString = _
      "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" _
      & Application.StartupPath & "¥sample.mdb"

      'コネクションオブジェクトの設定
      mCommand = New OleDbCommand()
      mCommand.Connection = mConn

      '********** << テーブル名を取得 >> **********
      Dim schemaTable As DataTable

      mConn.Open()

      schemaTable = mConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, _
                    New Object() {Nothing, Nothing, Nothing, "TABLE"})

      'メンバmTableNameListにテーブル名をセット
      Dim i As Integer
      For i = 0 To schemaTable.Rows.Count - 1
        mTableNameList.Add(schemaTable.Rows(i)("TABLE_NAME").ToString)
      Next i

    Catch oExcept As Exception
      Throw New Exception _
      ("clsDBIOのコンストラクタで例外発生" + oExcept.ToString)

    Finally
      'DB接続を閉じる
      If Not mConn Is Nothing Then
        If mConn.State = ConnectionState.Open Then
          mConn.Close()
        End If
      End If

    End Try

  End Sub

  '*******************************************************************
  ' 機能:キー値のレコードの有無を調べるメソッド
  ' 引数:テーブル名、キー値
  ' 戻値:ある-->True、ない-->False
  ' 備考:キー値は英数字 "_" "-" で構成されていること
  '*******************************************************************
  Public Function existKeyRecord( _
    ByVal parTableName As String, ByVal parKeyValue As String) As Boolean

    '第33号を参照願います。

  End Function

  '*******************************************************************
  ' 機能:複数キー値のレコードの有無を調べるメソッド
  ' 引数:テーブル名、キーフィールド名配列、キー値配列
  ' 戻値:ある-->True、ない-->False
  ' 備考:キー値は英数字のみで構成されている
  '*******************************************************************
  Public Function existKeyRecord(ByVal parTableName As String, _
                                 ByVal parKeyfield() As String, _
                                 ByVal parKeyValue() As String) As Boolean

    '第34号を参照願います。

  End Function

  '*******************************************************************
  ' 機能:引数にテーブルと主キー値を指定してレコードを取得するメソッド
  ' 引数:String型 テーブル名
  ' 引数:String型 主キー値
  ' 戻値:DataTable型 取得したレコード
  '*******************************************************************
  Public Function getKeyRecord(ByVal parTableName As String, _
                               ByVal parKeyValue As String) As DataTable

    Dim retDataTable As New DataTable()                 'リターン値

    Try

      '引数Nothing(未設定)チェック
      If parTableName = Nothing Then
        Throw New myDBIOException("引数テーブル名が未設定")
      End If
      If parKeyValue Is Nothing Then
        Throw New myDBIOException("引数主キー値が未設定")
      End If

      'テーブル名チェック
      Dim tblNames As String
      Dim existFlg As Boolean

      For Each tblNames In mTableNameList
        If tblNames = parTableName Then
          existFlg = True
          Exit For
        End If
      Next tblNames
      If Not existFlg = True Then
        Throw New myDBIOException("エラー:テーブル名不正")
      End If

      '前後の空白は除去する
      parKeyValue = parKeyValue.Trim()
      'キー値チェック(注:キー値は英数字と_と-で構成されている)
      If Not Regex.IsMatch(parKeyValue, "^[0-9a-zA-Z_¥-]+$") Then
        '英数字以外はエラー
        Throw New myDBIOException("エラー:キー値が正しくありません")
      End If

      'DB接続を開く
      mConn.Open()

      '主キーを取得
      Dim schemaTable As DataTable = _
      mConn.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, _
      New Object() {Nothing, Nothing, parTableName})

      Dim keyField As String
      Dim wherePhrase As String
      Dim oleDbPara As String

      mCommand.Parameters.Clear()
      keyField = schemaTable.Rows(0).Item(3).ToString
      wherePhrase = keyField + "= @key"

      '***** SQL文の引数設定 *****
      mCommand.Parameters.Clear()
      '入力引数の場合、Size指定は不要
      mCommand.Parameters.Add( _
      New OleDbParameter("@key", OleDbType.Char))

      '----------< コマンドパラメータに値を設定 >----------
      mCommand.Parameters("@key").Value = parKeyValue  'キー値の設定

      'SQL文設定
      mCommand.CommandText = _
      "SELECT * FROM " + parTableName + " WHERE " + wherePhrase

      'テーブルからレコード取得
      Dim dataAdapter As New OleDbDataAdapter()

      dataAdapter.SelectCommand = mCommand
      dataAdapter.Fill(retDataTable)

    Catch oExcept As Exception
      Throw New Exception _
      ("clsDBIOのgetKeyRecordで例外発生" + oExcept.ToString)

    Finally
      'DB接続を閉じる
      If Not mConn Is Nothing Then
        If mConn.State = ConnectionState.Open Then
          mConn.Close()
        End If
      End If

    End Try

    '◆戻値を設定してリターン
    Return retDataTable

  End Function

End Class

'--------------- << 独自エラーメッセージ用例外クラス >> --------------
Public Class myDBIOException
  Inherits ApplicationException

  Public Sub New(ByVal errorMessage As String)
    MyBase.New(errorMessage)
  End Sub

End Class

----------------------------------------------------------------------
            ■■ 次号予告 第36号(1月11日発行予定) ■■
1. VB.NETワンポイント
2. データベースアクセスクラスの汎用メソッドについて 5
======================================================================
VB.NET データベースプログラミング奮闘記
  発行者:ウェブ実験室(-----@-----)
          http://park5.wakwak.com/‾weblab/
----------------------------------------------------------------------
このメールマガジン(マガジンID: 0000128094)は、
インターネットの本屋さん『まぐまぐ』から配信されています。
  http://www.mag2.com/

【購読中止の方法】購読の中止は次のホームページからお願い致します。
  http://park5.wakwak.com/‾weblab/
  http://www.mag2.com/m/0000128094.htm
----------------------------------------------------------------------
このメールマガジン及び、「すぐ使えるADO.NET」ホームページで公開してい
るソースプログラム・データの利用により生じた損害等については、発行者は
一切責任を負いません。
ソースプログラムの再利用は自由です。著作権は発行者が所有します。
このメールマガジン及び、「すぐ使えるADO.NET」ホームページに掲載されて
いる会社名・製品名等は、各社の登録商標または商標です。
======================================================================

Copyright© すぐ使えるADO.NET. All rights reserved.