すぐ使えるADO.NET

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

本の紹介

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

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




【第43号】

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

すぐ使えるADO.NET --> サンプルプログラム満載
                      http://park5.wakwak.com/‾weblab/
======================================================================
             ■■ VB.NETワンポイント:現在の日時 ■■

主要なDBMSでは、SQL文に、現在の日時を取得するために、ANSIで規定されて
いるCURRENT_TIMESTAMP関数を利用することができます。

【SQL文記述例】
UPDATE 社員テーブル
SET 社員氏名=@sSimei, 社員カナ=@sKana, 更新日時=CURRENT_TIMESTAMP
WHERE 社員コード=@sCode AND 更新日時=@updateDate

clsDBIOクラスのupdateRecordメソッドでは、now()関数を使っています。
UPDATE 社員テーブル
SET 社員氏名=@sSimei, 社員カナ=@sKana, 更新日時=now()
WHERE 社員コード=@sCode AND 更新日時=@updateDate

clsDBIOクラスのinsertRecordメソッドでは、現在の日時をプログラムで取得
して、SQL文の引数に日付データを渡していました。

 mCommand.CommandText = _
 "UPDATE 社員テーブル " + _
 "SET 社員氏名=@sSimei, 社員カナ=@sKana, 更新日時=@newUpdateDate " + _
 "WHERE 社員コード=@sCode AND 更新日時=@updateDate"
            :
  mCommand.Parameters.Add _
  (New OleDbParameter("@newUpdateDate", OleDbType.Date))
            :
  mCommand.Parameters("@newUpdateDate").Value = Now()

CURRENT_TIMESTAMP関数が利用できる場合には、DBMS独自の関数は使わないほ
うが良いでしょう。


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

今号は、社員テーブルのレコードを更新するupdateRecordメソッドを、
clsDBIOクラスに追加します。引数には、clsUpdateSyainクラスのオブジェク
トを指定します。

社員テーブル以外のレコード更新メソッドも、updateRecordと同一名称にして、
それぞれのテーブル用の引数を用意して区別します。

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

◆SQL文の構築
更新日時が他で変更されていた場合には、更新できないように、WHERE句で、
"AND 更新日時=@updateDate" の条件を追加しています。@updateDateは、読み
込んだ時の更新日時をセットします。他で変更や削除されていれば、更新日時
が一致しないため、レコードが見つかりません。レコード更新用のSQL文は次
のようになります。

UPDATE 社員テーブル SET 社員氏名=@sSimei, 社員カナ=@sKana, 更新日時=now()
WHERE 社員コード=@sCode AND 更新日時=@updateDate"

◆更新処理
トランザクション制御は、レコード追加のinsertRecordメソッドとまったく同
様です。更新するレコードが1レコードでなかった場合には、ロールバックし
て、更新前の状態に戻します。

  Dim oTrans As OleDbTransaction
  oTrans = mConn.BeginTransaction
  mCommand.Transaction = oTrans

更新されたレコード数は、ExecuteNonQueryメソッドの戻り値でわかります。
この戻り値が1以外は、レコード更新の失敗となります。

  retInsertCount = mCommand.ExecuteNonQuery()

更新するレコードが1レコードならば、Commitメソッドでトランザクションを
完了します。

  oTrans.Commit()

更新するレコードが1レコードでなかった場合には、Transactionオブジェクト
のRollbackメソッドを使って、それまでの変更処理をすべてキャンセルして、
データベース内のテーブルデータをすべて変更前の状態に戻します。

  oTrans.Rollback()


'----------------- << データベースアクセスクラス >> -----------------
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()

    '第35号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag035.html

  End Sub

  '****************************************************************************
  ' 機能:社員テーブルの1レコードを更新するメソッド
  ' 引数:clsUpdateSyain型:更新する1レコード分のデータ
  ' 戻値:integer型:更新したレコード数
  '****************************************************************************
  Public Function updateRecord(ByVal parSyain As clsUpdateSyain) As Integer

    Dim retUpdateCount As Integer                'リターン値
    Dim keyList As New Collection()
    Dim i As Integer

    Try

      '★引数チェック
      If parSyain Is Nothing Then
        Throw New myDBIOException("引数が未設定")
      End If

      '----------<< 1.社員テーブルの1レコードを更新 >>----------
      '***** SQL文の設定 *****
      mCommand.CommandText = _
      "UPDATE 社員テーブル " + _
      "SET 社員氏名=@sSimei, 社員カナ=@sKana, 更新日時=now() " + _
      "WHERE 社員コード=@sCode AND 更新日時=@updateDate"

      '***** SQL文の引数設定 *****
      mCommand.Parameters.Clear()
      mCommand.Parameters.Add _
      (New OleDbParameter("@sSimei", OleDbType.Char, 20))
      mCommand.Parameters.Add _
      (New OleDbParameter("@sKana", OleDbType.Char, 40))
      mCommand.Parameters.Add _
      (New OleDbParameter("@sCode", OleDbType.Char, 5))
      mCommand.Parameters.Add _
      (New OleDbParameter("@updateDate", OleDbType.Date))

      '***** 引数に値を設定 *****
      mCommand.Parameters("@sSimei").Value = parSyain.pSyainSimei
      mCommand.Parameters("@sKana").Value = parSyain.pSyainKana
      mCommand.Parameters("@sCode").Value = parSyain.pSyainCode
      mCommand.Parameters("@updateDate").Value = parSyain.pUpdateTime

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

      '***** トランザクション開始 *****
      Dim oTrans As OleDbTransaction
      oTrans = mConn.BeginTransaction
      mCommand.Transaction = oTrans

      '***** データベースの更新を実行  *****
      retUpdateCount = mCommand.ExecuteNonQuery()

      If retUpdateCount = 1 Then
        '***** トランザクション完了 *****
        oTrans.Commit()
      Else
        '◆レコード更新に失敗したらロールバックして例外スロー
        oTrans.Rollback()
        Throw New myDBIOException _
        ("社員テーブル:レコード更新処理が失敗しました。")
      End If

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

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

  End Function

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

    '第33号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag033.html

  End Function

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

    '第34号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag034.html

  End Function

  '*******************************************************************
  ' 機能:引数にテーブルと主キー値を指定してレコードを取得するメソッド
  ' 引数:String型 テーブル名
  ' 引数:String型 主キー値
  ' 戻値:DataTable型 取得したレコード
  ' 備考:キー値は英数字 "_" "-" で構成されていること
  '*******************************************************************
  Public Function getKeyRecord(ByVal parTableName As String, _
                               ByVal parKeyValue As String) As DataTable

    '第35号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag035.html

  End Function

  '*******************************************************************
  ' 機能:複数キー値のレコードを取得するメソッド
  ' 引数:String型:テーブル名
  ' 引数:String型:主キーフィールド名配列
  ' 引数:String型:主キーフィールドに対応するキー値配列
  ' 戻値:DataTable型:取得したレコード情報
  ' 備考:キー値は英数字 "_" "-" で構成されていること
  '*******************************************************************
  Public Function getKeyRecord(ByVal parTableName As String, _
                               ByVal parKeyfields() As String, _
                               ByVal parKeyValues() As String) As DataTable

    '第36号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag036.html

  End Function

  '*******************************************************************
  ' 機能:テーブルの全レコードを取得するメソッド
  ' 引数:String型:テーブル名
  ' 戻値:DataTable型:取得したレコード
  '*******************************************************************
  Public Function getAllRecords(ByVal parTableName As String) As DataTable

    '第37号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag037.html

  End Function

  '*******************************************************************
  ' 機能:引数に指定した主キー値の範囲のレコードを取得するメソッド
  ' 引数:String型-->テーブル名
  ' 引数:String型-->主キーの最少値
  ' 引数:String型-->主キーの最大値
  ' 引数:String型-->主キーフィールド名(指定しない場合は、既定値の空文字列)
  ' 戻値:DataTable型:取得したレコード
  ' 備考:キー値は英数字 "_" "-" で構成されていること
  '*******************************************************************
  Public Function getRecordsOfRangeOfKey( _
                        ByVal parTableName As String, _
                        ByVal parMinValueOfKey As String, _
                        ByVal parMaxValueOfKey As String, _
                        Optional ByVal parKeyfield As String = "") _
                        As DataTable

    '第38号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag038.html

  End Function

  '*******************************************************************
  ' 機能:テーブル対応の1行を生成するメソッド
  ' 引数:String型:テーブル名
  ' 戻値:DataRow型:生成した行
  '*******************************************************************
  Public Function createDataRow(ByVal parTableName As String) As DataRow

    '第39号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag039.html

  End Function

  '*******************************************************************
  ' 機能:テーブル名をチェックするメソッド
  ' 引数:String型:テーブル名
  ' 戻値:Boolean型:引数のテーブル名が正しい時True、誤っている時False
  '*******************************************************************
  Private Function existTable(ByVal parTableName As String) As Boolean

    '第39号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag039.html

  End Function

  '*******************************************************************
  ' 機能:テーブルに1レコードを追加するメソッド
  ' 引数:clsInsertSyain型:追加する1レコード分のデータ
  ' 戻値:integer型:追加したレコード数
  '*******************************************************************
  Public Function insertRecord(ByVal parSyain As clsInsertSyain) As Integer

    '第41号を参照願います。
    'http://park5.wakwak.com/‾weblab/mag041.html

  End Function

End Class

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