すぐ使えるADO.NET

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

本の紹介

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

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




【第33号】

 第33号(2005.11.2発行)
======================================================================
           ★★ VB.NETデータベースプログラミング奮闘記 ★★
----------------------------------------------------------------------
いつもご購読ありがとうございます。ADO.NETの基本的なプログラミングを中
心に掲載しますので、今後ともよろしくお願い申し上げます。

すぐ使えるADO.NET --> サンプルプログラム満載
                      http://park5.wakwak.com/‾weblab/
======================================================================
          ■■ VB.NETワンポイント:ExecuteScalarメソッド ■■

OleDbCommandクラスのExecuteScalarメソッドは、データベースから、レコー
ド数、平均値、最大値、最小値、合計値などの単一の値を取得する場合に使用
すると便利なメソッドです。このメソッドの戻り値は、オブジェクト型ですか
ら必要に応じて型変換します。"SELECT 関数(fieldName) FROM tableName" の
SQL文を使って単一の値を得る場合には、特に簡単です。

◆総レコード数:SELECT COUNT(*) FROM tableName
  Dim Count As Integer = CInt(mCommand.ExecuteScalar())

◆テキスト型フィールドの最大値:SELECT MAX(fieldName) FROM tableName
  Dim Maximum As String = CStr(mCommand.ExecuteScalar())

◆テキスト型フィールドの最小値:SELECT MIN(fieldName) FROM tableName
  Dim Minimum As String = CStr(mCommand.ExecuteScalar())

社員テーブルに存在するレコードから、部門コードフィールド(テキスト型)の
最大値を求める場合は、次のようになります。

  '********** << 最大値取得 >> *********
  'SQL文設定
  mCommand.CommandText = _
    "SELECT MAX(部門コード) FROM 社員テーブル"

  Dim Maximum As String = CStr(mCommand.ExecuteScalar())

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

今回は、existKeySyainメソッドを改造して、DBアクセスクラスの汎用的な
キー値のレコードの有無を調べるメソッドを作成していきます。

existKeySyain()、existKeyBumon()、existKeyZeiRitsu()、… とテーブルの
数だけメソッドを作るのもひとつの方法ですが、汎用的なexistKeyRecord
メソッドをいくつか作って、対応するようにするとたいへん便利です。

今号では、テーブルの主キーがテキスト型の1フィールドのメソッドを作成し
ます。前号で紹介したexistKeySyainメソッドを、汎用的に使えるように直し
ます。

まず、次のSQL文の社員テーブル固有の社員テーブルと社員コードの部分を汎
用的に使えるように修正します。

  mCommand.CommandText = _
  "SELECT COUNT(*) FROM 社員テーブル WHERE 社員コード = @Key"

テーブル名称は、引数にテーブル名を追加して、メソッドの引数から受け取れ
るようにします。また、WHERE句の社員コードは、前号で紹介した主キーを取
得するコネクションクラスのGetOleDbSchemaTableメソッドを使って取得しま
す。

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

メソッドの引数でテーブル名を受け取るようにしたため、テーブル名のチェッ
クを追加します。テーブル名はコンストラクタで取得したmTableNameListに保
管してありますから、引数のテーブル名がmTableNameListになければ、エラー
として例外をスローします。

  'テーブル名チェック
  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

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

正規表現^[0-9a-zA-Z_¥-]+$ について分かりやすく書くと、

  ^              ---> 文字列の先頭から
  [0-9a-zA-Z_¥-] ---> 0から9、またはaからz、またはAからZ、
                      または_、 または- が
  +              ---> 1文字以上連続している
  $              ---> 文字列で終わっている

となります。

これで、社員テーブルのキー値レコードの存在をチェックするexistKeySyain
メソッドを修正して作った汎用的なexistKeyRecordメソッドの完成です。

次号では、複数のキーフィールドを持つテーブル用のキー値レコードの存在を
チェックするexistKeyRecordメソッドを追加します。

--【プログラムソースリスト】------------------------------------------
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()

  '*******************************************************************
  ' 機能:コンストラクタ
  ' 引数:なし
  '*******************************************************************
  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

      mConn.Close()

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

    End Try

  End Sub

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

    Dim retBool As Boolean                      'リターン値

    Try

      'テーブル名チェック
      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 COUNT(*) FROM " + parTableName + " WHERE" + wherePhrase

      'レコード件数取得
      Dim Count As Integer = CInt(mCommand.ExecuteScalar())

      '----------< 戻値を設定 >----------
      If Count = 1 Then
        retBool = True
      Else
        retBool = False
      End If

    Catch oExcept As myDBIOException
      Throw New myDBIOException(oExcept.Message)

    Catch oExcept As Exception
      Throw New Exception _
      ("clsTableSyainのexistKeyRecordで例外発生" + 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 retBool

  End Function

End Class

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

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

End Class

----------------------------------------------------------------------
            ■■ 次号予告 第34号(11月25日発行予定) ■■
1. VB.NETワンポイント
2. データベースアクセスクラスの汎用メソッドについて 3
======================================================================
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.