コンテンツ |
 |
|
|
 |
 |
著者 |
Essma Hasin
品質保証エンジニア
Neneva Technologies
|
 |
|
|
| |
|
はじめに
IBM® DB2® V8.1は、MDC(多次元クラスタリング)やOnline
Reorgなどのエンジン機能面でのさまざまな新しい拡張、およびHealth Center、Development Center、Development
Add-Ins for Microsoft® Visual Studio 6などの優れた新しいツールを盛り込んだ、画期的な新リリースです。
DB2 Development Add-In for Visual Basic 6は、データベースのプロシージャーや関数を利用するアプリケーションをはじめ、n層アプリケーション開発を大幅に簡素化する優れたツールですが、Visual
Basic開発者にとっては、ADOプログラミングAPIを使ったDB2開発の基本を理解することが重要です。
この記事では、4つの基本データベース操作を実行するADOオブジェクト・モデルについて説明します。その操作とは、Visual Basicクライアント・アプリケーションを使ったDB2
Universal DatabaseTMテーブルのレコードの選択、挿入、更新、削除です。その後適宜、これらの操作を実行する2つの異なる方法について説明します。
- ダイレクトSQLステートメントの使用
- ADO Recordsetメソッド呼び出しの使用
BasicADOクライアント・サーバー・アプリケーション
この記事全体を通して、ADOを使ったDB2アプリケーション開発の実例として、BasicADOというVisual Basicアプリケーションのサンプルからコードの断片を抜粋して説明します。
図1.BasicADOサンプル・アプリケーション
BasicADOアプリケーションは、IDENTITY、INTEGER、VARCHAR、DATE、TIME、DECIMALの6つの基本DB2データ型を持つ単一テーブルのレコードの選択、挿入、更新、削除を行います。
アプリケーションのダウンロード、インストール、実行の手順については「サンプル・アプリケーションのダウンロード」のセクションを参照してください。
DB2レコードを選択する
ADOを使ってDB2からレコードを選択するには、SQL SELECTステートメントを使います。ADO CommandオブジェクトまたはADO
Recordsetオブジェクトのどちらかを使って、ADO Connectionオブジェクトにこのステートメントを実行します。
データ・レコードを照会するには、次の標準のステップが必要です。
- ADO Connectionオブジェクトを作成し、セットアップします。
- この接続のOpenメソッドを使って、DB2データベースに接続します。
- ADO Commandオブジェクトを作成し、セットアップします。該当するSQL SELECTステートメントをCommandTextとします。
- ADO Recordsetオブジェクトを作成し、コマンドのExcuteメソッドの呼び出しからの戻り値にこれを割り当てます。
- 接続のCloseメソッドを使って、ADO Connectionオブジェクトを閉じます。
IBMDADB2を使ったADO Connectionオブジェクト
Visual BasicアプリケーションからDB2データベースにアクセスするために必要な最初のステップは、必要なADO Connectionオブジェクトの作成とセットアップです。DB2に接続するために設定しなければならない2つのプロパティーがあります。
推奨:DB2データベースへの接続時には、クライアント・サイドのカーソルを使ってください。具体的には、CursorLocationプロパティーに値としてadUseClientを割り当てます。
DB2には、専用のOLE DBプロバイダーであるIBMDADB2が同梱されていますので、DB2への接続に必要な接続文字列は次の形式になります。
| |
Provider=IBMDADB2; DSN=DatabaseAlias;
|
次のように、オプションでユーザー名とパスワードを接続文字列に含めることもできます。
| |
User ID=UserName; Password=UserPassword;
|
リスト1にGetConnection関数のコードを示します。この関数は、ADO Connectionオブジェクトの作成と初期化を行います。
リスト1.BasicADO − GetConnection関数
| |
' Create and return ADO Connection Object
Public Function GetConnection( _
strDBName As String, _
Optional strUserName As String = "", _
Optional strPassword As String = "") As ADODB.Connection
On Error GoTo GetConnection_ErrHandler
Dim strConnectionString As String
strConnectionString = "Provider=IBMDADB2; DSN=" & strDBName
If strUserName <> "" And strPassword <> "" Then
strConnectionString = strConnectionString & "; User ID=" & strUserName _
& "; Password=" & strPassword
End If
' Create new ADO connection object
Dim adoConnection As New ADODB.Connection
With adoConnection
.CursorLocation = adUseClient
.ConnectionString = strConnectionString
End With
' Return new ADO connection object
Set GetConnection = adoConnection
Set adoConnection = Nothing
Exit Function
GetConnection_ErrHandler:
MsgBox "Error Code: " & Err.Number & vbNewLine & _
"Description: " & Err.Description & vbNewLine & _
"Source: " & Err.Source, _
vbOKOnly + vbCritical
Err.Clear
Set GetConnection = Nothing
End Function
|
SQLを実行する前にまず目的の接続を開くこと、実行終了後には接続を必ず閉じることに留意してください。具体的には、ADO ConnectionオブジェクトのOpenメソッドとCloseメソッドを使用します。
IBM DB2 V8 Development Add-Inの使用
DB2
Development Add-Ins for Visual Basic 6を使って、プロジェクト・データベース用にADO Connectionオブジェクトを作成し初期化するのに必要なADOコードを自動的に生成することができます。上記のリスト1に示したサンプル・コードは、Add-Inからの生成コードに基づいたものです。Visual
Studio 6.0を使ってDB2アプリケーションを構築するときは、DB2 Development Add-Inを使用することを強くお薦めします。
ADO Commandオブジェクトを作成する
DB2データベース・サーバーに対してSQLを実行するには、最初に、ADO Commandオブジェクトの作成と初期化を行わなければなりません。そうすれば、ADO
RecordsetオブジェクトのOpenメソッドを使って、目的のコマンドSQLを実行することができます。
リスト2に、QueryRecords関数のコードを示します。この関数は、ADO Commandオブジェクトの作成と初期化を行い、ADO RecordsetオブジェクトのOpenメソッドを実行します。
リスト2.BasicADO − QueryRecords関数
| |
Function QueryRecords(ByRef adoConnection As ADODB.Connection) As
ADODB.Recordset
'Create ADO objects
Dim adoCommand As ADODB.Command
Dim adoRecordSet As ADODB.Recordset
On Error GoTo QueryRecords_ErrHandler
Set adoCommand = New ADODB.Command
With adoCommand
.CommandType = adCmdText
.ActiveConnection = adoConnection
.CommandText = "SELECT tINT, tVARCHAR, tDATE, tTIME, tDECIMAL FROM BASICADO"
End With
'Create record set
Set adoRecordSet = New ADODB.Recordset
adoRecordSet.Open adoCommand, , adOpenStatic, adLockOptimistic
Set QueryRecords = adoRecordSet
Set adoRecordSet = Nothing
Set adoCommand = Nothing
Exit Function
QueryRecords_ErrHandler:
Call ShowAllErrors(adoConnection)
Set QueryRecords = Nothing
End Function
|
ADO Commandオブジェクトの作成と初期化を行う
ADO Commandオブジェクトを使用するには、最初にオブジェクトの新しいインスタンスを作成し、その後で必須のプロパティーを初期化する必要があります。
SQLステートメントを実行するには、CommandTypeプロパティーをadCmdTextに設定しなければなりません。データベースのストアード・プロシージャーを呼び出す場合は、このプロパティーをadCmdStoredProcに設定します。
CommandTextプロパティーは、実行する実際のSQL、またはストアード・プロシージャー名に設定します。BasicADOアプリケーションでは、テーブルの全レコードのすべての該当列を照会するのに必要なSELECTステートメントを指定しました。
ActiveConnectionプロパティーは、すでに開いている目的のADO Connectionオブジェクトに設定します。
ADO Recordsetオブジェクトの作成と初期化を行う
ADO Commandオブジェクトに格納されたSQLを実行するには、ADO Recordsetオブジェクトの新しいインスタンスを作成し、その後にOpenメソッドを呼び出して、目的のADO
Commandオブジェクトに入ります。Openメソッドの残りの必須パラメーターには、CursorTypeとLockingTypeが含まれます。
CursorTypeパラメーターは、adOpenStaticに設定することができます。とりうる値の詳細についてはオンラインのADOマニュアルを参照してください。LockingTypeパラメーターは、adLocOptimisticに設定することができます。これについても、とりうる値の詳細は、オンラインのADOマニュアルを参照してください。
IBM DB2 V8 Development Add-Inの使用
DB2 Development Add-Ins for Visual Basic 6を使って、サーバー・サイドのストアード・プロシージャーと関数を呼び出すのに必要なADOコードを自動的に生成することができます。このアドインにより、ADO
CommandオブジェクトとRecordsetオブジェクト、加えて、パラメーターをもつプロシージャーと関数に必要なすべてのADOパラメーター・オブジェクトが生成されます。
SQL Assist照会ビルダーを呼び出して、ADO Command用に必要なSQLをグラフィカルに構築することもできます。
私が便利と感じた機能の1つは、アプリケーションをテストしながら、サーバー・サイド・テーブルの内容をサンプリングする機能です。
ADO Recordsetデータにアクセスする
結果セットを返すADOコマンドを実行後、ADO Recordsetオブジェクトを使って、その結果セットにアクセスすることができます。複数の結果セットを返すADOコマンドについては、ADO
RecordsetオブジェクトのNextRecordSetメソッドを使うと、次のマルチレコード結果セットに進むことができます。
現在の結果セットの現在行の各列にアクセスするには、3通りの方法があります。
使用するメソッドにかかわらず、次のアクセス・メカニズムを使って、各列の値を取得または設定することができます。
| |
SomeVar = Recordset!FiledName ' To lookup the field value
Recordset!FieldName = SomeValue ' To set the field value
|
Recordset!FieldNameの使用
Recordset!FieldName構文を使うと、現在行の各列にごく簡単にアクセスすることができます。この構文ではFieldNameは列名を指します。列名に区切りが含まれている場合は、この方法を使用しないでください。フィールド名は、大文字小文字を区別しません。これは、私が最もよく使用している構文です。
Recordset.Fields("FieldName") の使用
構文の使い方は、Recordset!FieldNameと非常によく似ていますが、Recordset.Fields("FieldName")
では、区切りのある列名を使用することができます。
Using Recordset.Fields(FieldIndex) の使用
結果セットに列名が含まれない場合、あるいは各結果セット列により速くアクセスしたい場合は、Recordset.Fields(FieldIndex)
構文が使えます。この構文を使うには、結果セットの列の順序がわかっていなければなりません。照会を変更して追加の列を含める場合は、遡って、フィールド・インデックスを調整しなければならない場合があります。
ADO Recordsetを使ってListViewを追加する
結果セットの行に繰り返しアクセスし、Visual Basic ListViewのAddメソッドを使用することによって、指定したADO Recordsetオブジェクトのデータ行をListViewオブジェクトにプログラマチックに追加することができます。
ADO Recordsetの行の間を前後に移動するには、MoveFirst、MoveLast、Move Next、MovePreviousメソッドを使います。また、EOFブール・メソッドを使って、結果セットの末尾をチェックすることもできます。
リスト3にDisplayRecords関数のコードを示します。この関数は、リスト2に示したQueryRecords関数から生成されたレコードを、BasicADOアプリケーションのListViewオブジェクトに追加します。
リスト3. BasicADO − DisplayRecordsサブルーチン
| |
Private Sub DisplayRecords()
Dim adoRecordSet As ADODB.Recordset
Set adoRecordSet = modDBUtil.QueryRecords(adoCon)
'Populate list view with records manually
lstRecords.ListItems.Clear
If Not adoRecordSet Is Nothing Then
Dim lstItem As ListItem
While Not adoRecordSet.EOF()
Set lstItem = lstRecords.ListItems.Add(, , adoRecordSet!tINT)
lstItem.SubItems(1) = adoRecordSet!tVARCHAR & ""
lstItem.SubItems(2) = GetDateValue(adoRecordSet!tDATE & "")
lstItem.SubItems(3) = GetTimeValue(adoRecordSet!tTIME & "")
lstItem.SubItems(4) = FormatCurrency(adoRecordSet!tDECIMAL & "")
adoRecordSet.MoveNext
Wend
End If
Set adoRecordSet = Nothing
Set lstItem = Nothing
End Sub
|
ヒント − NULL値の正常な処理
NULL列値については、上記のように& ""を挿入することで簡単に処理できます。このコードの断片は、NULL文字列がフィールド値に連結されていることを意味しています。これにより、Visual
Basic変数にNULLフィールド値を割り当てた場合に生成されるランタイム・エラーが回避されます。
あるいは、次のコードを使って、割り当ての前にNULL値をチェックすることができます。
| |
If adoRecordSet.Fields("SomeField").ActualSize > 0 Then
SomeVar = adoRecordSet.Fields("SomeField")
End If
|
ヒント − 日付け列のフォーマット
Visual Basic関数のFormatまたはFormateDateTimeを使って、レコード・セットの日付け列を正しくフォーマットすることができます。独自のカスタム・フォーマットを指定できるという点で、Format関数の方が柔軟です。FormateDateTimeでは、vbShortDateやvbLongDate、vbGeneralDateなどの、標準のロケール固有の日付けフォーマット・オプションを使用することができます。
これらのフォーマット関数を使用する場合は、その前に、Visual Basic関数のDateValueを使って、適正な日付けデータ型に変換します。
リスト4にGetDateValue関数のコードを示します。この関数を使って、DATE列型を正しくフォーマットすることができます。
リスト4. BasicADO − GetDateValue関数
| |
Public Function GetDateValue(ByRef strDate As String) As String
If strDate <> "" Then
GetDateValue = Format(DateValue(strDate), "mm/dd/yyyy")
'GetDateValue = FormatDateTime(DateValue(strDate), vbGeneralDate)
Else
GetDateValue = ""
End If
End Function
|
ヒント − 時刻列のフォーマット
DATEデータ型と異なり、TIMEデータ型の列を表示する場合は、何らかの偽りの日付とそれに続いて実際の時刻値を取得します。Visual Basic関数のFormatまたはFormateDateTimeを使って、レコード・セットの日付列を正しくフォーマットすることができます。独自のカスタム・フォーマットを指定できるという点で、Format関数の方が柔軟です。FormateDateTimeでは、vbShortTimeやvbLongTimeなどの、標準のロケール固有の時刻フォーマット・オプションを使用することができます。
これらのフォーマット関数を使用する場合は、その前に、Visual Basic関数のTimeValueを使って、適正な時刻データ型に変換します。
リスト5にGetTimeValue関数を示します。この関数を使って、TIME列型を正しくフォーマットすることができます。
リスト5. BasicADO − GetTimeValue関数
| |
Public Function GetTimeValue(ByRef strTime As String) As String
If strTime <> "" Then
GetTimeValue = Format(TimeValue(strTime), "hh:nn:ss")
'GetTimeValue = FormatDateTime(TimeValue(strTime), vbLongTime)
Else
GetTimeValue = ""
End If
End Function
|
ヒント − 10進数列のフォーマット
10進数型をフォーマットするには、さまざまな方法があります。例を以下に示します。
- FormatCurrency関数は、10進数をロケール固有の通貨値に変換します。
- FormatPercent関数は、10進数をパーセント値に変換します。
- FormatNumber関数は、10進数を、指定した数の先行ゼロおよび/または小数位を持つ特定の数値に変換します。
新しいDB2レコードを挿入する
ユーザー入力または何らかの生成されたデータに基づいて、既存のデータベース・テーブルに新しいレコードを挿入することが必要な場合が数多くあります。この操作を実行するには、さまざまな方法があります。以下はそのうちの2つの方法です。
- SQL INSERTステートメントを使用する
- ADO RecordsetオブジェクトのAddメソッドを使用する
2つの方法の重要な相違として、INSERTステートメントは、挿入する各レコードに必要とされ、ADO Recordsetメソッドでは、複数の挿入をバッチにして、ADO
RecordsetオブジェクトのUpdateメソッドを使って1つのユニットとして実行することができるという点が挙げられます。
INSERTステートメントを使って挿入する
SQL INSERTステートメントを使ってレコードを挿入するには、次の手順が必要です。
- 適正なSQL INSERTステートメントをコマンド・テキストとして持つ、ADO Commandオブジェクトの作成と初期化を行います。'?'パラメーター・マーカーを使って、実際の列の値を定位置パラメーターとして渡すことができます。これにより、同じADOコマンドを使って、複数のレコードを挿入することが可能です。
- 定位置パラメーターの値を新しい行の実際の列の値に設定します。
- ADO CommandオブジェクトのExecuteメソッドを使って、コマンドを実行します。
- パラメーター値をリセットし、挿入する各追加行について、コマンドを再実行します。
リスト6にInsertUsingInsertサブルーチンのコードを示します。このサブルーチンは、SQL INSERTステートメントを使って複数行の挿入を実行します。同じADOコマンドを使って複数行を挿入します。
リスト6. BasicADO − InsertUsingInsertサブルーチン
| |
Sub InsertUsingInsert(ByRef adoConnection As ADODB.Connection)
'Create ADO objects
Dim adoCommand As ADODB.Command
On Error GoTo InsertUsingInsert_ErrHandler
Set adoCommand = New ADODB.Command
With adoCommand
.CommandType = adCmdText
.ActiveConnection = adoConnection
.CommandText = "INSERT INTO BASICADO (tINT, tVARCHAR, tDATE,
tTIME, tDECIMAL) VALUES(?,?,?,?,?)"
End With
'Add Parameters to the Command object
Dim adoParm_tINT As Parameter
Set adoParm_tINT = adoCommand.CreateParameter("tINT", _
adInteger, _
adParamInput)
Call adoCommand.Parameters.Append(adoParm_tINT)
Dim adoParm_tVARCHAR As Parameter
Set adoParm_tVARCHAR = adoCommand.CreateParameter("tVARCHAR", _
adVarChar, _
adParamInput, _
256)
Call adoCommand.Parameters.Append(adoParm_tVARCHAR)
Dim adoParm_tDATE As Parameter
Set adoParm_tDATE = adoCommand.CreateParameter("tDATE", _
adDBDate, _
adParamInput)
Call adoCommand.Parameters.Append(adoParm_tDATE)
Dim adoParm_tTIME As Parameter
Set adoParm_tTIME = adoCommand.CreateParameter("tTIME", _
adDBTime, _
adParamInput)
Call adoCommand.Parameters.Append(adoParm_tTIME)
Dim adoParm_tDECIMAL As Parameter
Set adoParm_tDECIMAL = adoCommand.CreateParameter("tDECIMAL", _
adDecimal, _
adParamInput)
Call adoCommand.Parameters.Append(adoParm_tDECIMAL)
'Set the values and execute the 1st insert
adoParm_tINT.Value = 1
adoParm_tVARCHAR.Value = "Hello world at 1!"
adoParm_tDATE.Value = "21/02/1997"
adoParm_tTIME.Value = "12:00:01"
adoParm_tDECIMAL.Value = "1111.11"
Call adoCommand.Execute
'Set the values and execute the 2nd insert
adoParm_tINT.Value = 2
adoParm_tVARCHAR.Value = "Hello world at 2!"
adoParm_tDATE.Value = "01/03/1999"
adoParm_tTIME.Value = "12:00:02"
adoParm_tDECIMAL.Value = "2222.22"
Call adoCommand.Execute
Set adoCommand = Nothing
Exit Sub
InsertUsingInsert_ErrHandler:
Call ShowAllErrors(adoConnection)
End Sub
|
ADO Parameterオブジェクトの作成と初期化を行う
定位置パラメーターまたはストアード・プロシージャー・パラメーターを必要とするADO Commandを使用する場合に、ADO CommandのADO
Parametersコレクションを使って、これらのパラメーターの値を設定し、取得することができます。
各パラメーターのオブジェクトを作成し、初期化して、ADO Commandオブジェクトのパラメーター・コレクションに追加することが必要です。入力パラメーター値は、コマンド実行前に設定し、出力パラメーターは、コマンド実行後に読み取らなければなりません。
リスト6に示したように、コマンド・パラメーターを使用するには、次の手順を実行します。
- コマンドのCreateParameterメソッドを使って、新しいADO Parameterオブジェクトを作成します。パラメーターの名前、型、サイズ、オプション値を指定します。
- コレクションのAppendメソッドを使って、コマンドのParametersコレクションにパラメーターを追加します。
- 入力値をパラメーターのValueプロパティーに割り当て、入力パラメーターの値を指定します。
- コマンドを実行します。
- パラメーターのValueプロパティーを使って、出力パラメーターの値を読み取ります。
重要:各パラメーターのDB2 SQL型に正しく対応するADOデータ型を使用してください。DB2 V8.1 Development
Add-Inを使用すると、ストアード・プロシージャー・パラメーターは自動的に作成され、セットアップされます。これにより、DB2ベースのアプリケーション開発がはるかに容易なものとなります。
ADO Recordsetを使って挿入する
ADO Recordsetを使ってレコードを挿入するには、次の手順が必要です。
- レコードの新しいリストを保持するため、ADO Commandとその結果のADOレコード・セットを作成します。ADOレコード・セットにレコードが入っている必要はありません。重要なのは、行を挿入するための適正な列のリストです。そのために、ADOコマンドのSELECTステートメントには、false条件のWHERE文節を含めることができます。
- ADO接続を開きます。
- ADOコマンドを実行し、おそらくは空のADOレコード・セットを検索します。
- AddNewメソッドを使って、ADOレコード・セットに新しいレコードを追加します。
- レコード・セットのデータにアクセスする3つの方法のいずれかを使って、新しく追加したレコードのそれぞれについて各列の値を設定します。
- ADOレコード・セットのUpdateメソッドを呼び出して、DB2テーブルに新しいレコードを挿入します。
- ADO接続を閉じます。
リスト7にInsertUsingRecordsetサブルーチンのコードを示します。このサブルーチンは、ADO Recordsetオブジェクトを使って、複数行の挿入を実行します。
リスト7. BasicADO − InsertUsingRecordsetサブルーチン
| |
Sub InsertUsingRecordset(ByRef adoConnection As ADODB.Connection)
'Create ADO objects
Dim adoCommand As ADODB.Command
Dim adoRecordSet As ADODB.Recordset
On Error GoTo InsertUsingRecordset_ErrHandler
Set adoCommand = New ADODB.Command
With adoCommand
.CommandType = adCmdText
.ActiveConnection = adoConnection
.CommandText = "SELECT tINT, tVARCHAR, tDATE, tTIME, tDECIMAL FROM
BASICADO WHERE tINT = 0"
End With
'Create record set
Set adoRecordSet = New ADODB.Recordset
adoRecordSet.Open adoCommand, , adOpenStatic, adLockOptimistic
'Update values for row 1
adoRecordSet.AddNew
adoRecordSet!tINT = 1
adoRecordSet!tVARCHAR = "Hello world at 1!"
adoRecordSet!tDATE = "21/02/1997"
adoRecordSet!tTIME = "12:00:01"
adoRecordSet!tDECIMAL = "1111.11"
'Update values for row 2
adoRecordSet.AddNew
adoRecordSet!tINT = 2
adoRecordSet!tVARCHAR.Value = "Hello world at 2!"
adoRecordSet!tDATE = "01/03/1999"
adoRecordSet!tTIME = "12:00:02"
adoRecordSet!tDECIMAL = "2222.22"
'Execute all inserts
Call adoRecordSet.Update
Set adoRecordSet = Nothing
Set adoCommand = Nothing
Exit Sub
InsertUsingRecordset_ErrHandler:
Call ShowAllErrors(adoConnection)
End Sub
|
適正なDATEおよびTIME値文字列を使って、新しく挿入したレコードに対応する列の値を設定してください。
既存のDB2レコードを更新する
レコードは多くの場合、データベース・アプリケーションの一部として更新されます。この更新は、ユーザーが特定のオブジェクト・レコードのプロパティー・ダイアログでフィールドを修正した結果であるかもしれませんし、あるいは、何らかのユーザー・アクションまたはトランザクションの間接的な結果であるかもしれません。更新操作を実行するには、さまざまな方法があります。以下はそのうちの2つの方法です。
- SQL UPDATEステートメントを使用する
- ADO Recordsetオブジェクトを使ってフィールド値を直接操作する
Recordset更新メカニズムを使用する重要な利点の1つは、通常の場合、表示目的でレコードがすでに照会済みであるという点です。したがって、レコードの更新は、クライアント・マシン上で変更して、サーバーに戻すだけで済みます。反対に、UPDATEステートメントは、WHERE文節を使ってサーバー側で実行されなければなりません。これは、更新するレコードを再識別する必要があることを意味します。
UPDATEステートメントを使って更新する
SQL UPDATEステートメントを使ってレコードを更新するには、次の手順が必要です。
- 適正なSQL UPDATEステートメントをコマンド・テキストとして持つADO Commandオブジェクトの作成と初期化を行います。'?'パラメーター・マーカーを使って、実際の列の値およびWHERE文節の当該列の値を定位置パラメーターとして渡すことができます。これにより、同じADOコマンドを使って、動的な更新、複数のレコードの更新、または複数のレコード・グループの更新が行えます。
- 定位置パラメーターの値を実際の列の値に設定します。
- ADO CommandオブジェクトのExecuteメソッドを使って、コマンドを実行します。
- パラメーター値をリセットし、更新する各追加行または行のグループについて、コマンドを再実行します。
リスト8にUpdateUsingUpdateサブルーチンのコードを示します。このサブルーチンは、SQL UPDATEステートメントを使って複数行の更新を実行します。同じADOコマンドを使って複数の行または行のグループを更新することができます。
リスト8.BasicADO − UpdateUsingUpdateサブルーチン
| |
Sub UpdateUsingUpdate(ByRef adoConnection As ADODB.Connection)
'Create ADO objects
Dim adoCommand As ADODB.Command
On Error GoTo UpdateUsingUpdate_ErrHandler
Set adoCommand = New ADODB.Command
With adoCommand
.CommandType = adCmdText
.ActiveConnection = adoConnection
.CommandText = "UPDATE BASICADO " & _
"SET tVARCHAR = 'Bye world!' " & _
"WHERE tINT = ?"
End With
'Add Parameters to the Command object
Dim adoParm_tINT As Parameter
Set adoParm_tINT = adoCommand.CreateParameter("tINT", _
adInteger, _
adParamInput)
Call adoCommand.Parameters.Append(adoParm_tINT)
'Update all records having tINT = 1
adoParm_tINT.Value = 1
Call adoCommand.Execute
Set adoCommand = Nothing
Exit Sub
UpdateUsingUpdate_ErrHandler:
Call ShowAllErrors(adoConnection)
End Sub
|
ADO Recordsetを使って更新する
ADO Recordsetを使ってレコードを更新するには、次の手順が必要です。
- 表示とその後で更新を行うレコードのリストを保持するため、ADO Commandとその結果のADOレコード・セットを作成します。ADOレコード・セットは、必ずしも更新するレコードのみである必要はありません。
- ADO接続を開きます。
- ADOコマンドを実行し、ADOレコード・セットとして該当する行の初期リストを検索します。Recordset更新が動作するためには、基本キー列を入れる必要があります。下記のヒントを参照してください。
- Findメソッドを使って、ADOレコード・セットの各レコードに繰り返しアクセスして、レコードを特定します。
- レコード・セットのデータにアクセスする3つの方法のいずれかを使って、新しい値に更新する各レコードについて各列の値を設定します。
- ADOレコード・セットのUpdateメソッドを呼び出して、DB2テーブルで複数行更新を実行します。
- ADO接続を閉じます。
リスト9にUpdateUsingRecordsetサブルーチンのコードを示します。このサブルーチンは、ADO Recordsetオブジェクトを使って、複数行更新を実行します。
リスト9.BasicADO − UpdateUsingRecordsetサブルーチン
| |
Sub UpdateUsingRecordset(ByRef adoConnection As ADODB.Connection)
'Create ADO objects
Dim adoCommand As ADODB.Command
Dim adoRecordSet As ADODB.Recordset
On Error GoTo UpdateUsingRecordset_ErrHandler
Set adoCommand = New ADODB.Command
With adoCommand
.CommandType = adCmdText
.ActiveConnection = adoConnection
'Update requires primary key, so need to select tKEY
.CommandText = "SELECT tKEY, tINT, tVARCHAR, tDATE, tTIME, tDECIMAL
FROM BASICADO"
End With
'Create record set
Set adoRecordSet = New ADODB.Recordset
adoRecordSet.Open adoCommand, , adOpenStatic, adLockOptimistic
'Update all records having tINT = 2 (requires primary key)
Call adoRecordSet.Find("tINT = 2")
While Not adoRecordSet.EOF()
adoRecordSet!tVARCHAR = "Bye world!"
adoRecordSet.MoveNext
Call adoRecordSet.Find("tINT = 2")
Wend
'Workaround for BOF ADO bug!
If adoRecordSet.RecordCount > 0 Then
adoRecordSet.MoveFirst
End If
'Execute the update
Call adoRecordSet.Update
Set adoRecordSet = Nothing
Set adoCommand = Nothing
Exit Sub
UpdateUsingRecordset_ErrHandler:
Call ShowAllErrors(adoConnection)
End Sub
|
ヒント − 基本キーを入れる
レコード・オブジェクトの基本キーが更新されることはめったにありませんが、照会に基本キー列を入れる必要があります。基本キーを使って、更新の必要なレコードを識別するための基礎となる適正なUPDATE
SQLをADOが生成できるようにするためには、これは必須です。
基本キーを入れることができなかった場合は、図2に示すようなランタイム・エラーが生成されます。
図2.BasicADO − 基本キーのない更新の実行時に生成されるエラー
ヒント − EOF ADOエラーの回避
私は、BasicADOアプリケーションに取り組んでいた時に、ADOレコード・セットの行インデックスが最後のレコードを過ぎた後のUpdateメソッドの呼び出しで、解決しなければならないバグがあることに気付きました。リスト8のUpdateUsingUpdateコードを見るとわかるように、繰り返しによってすべてのレコードを辿れるように、whileループを使っています。ループの後に直接Updateメソッドを呼び出すと、図3に示すエラー・メッセージが生成されます。
図3.BasicADO − EOFに達した後のUpdate呼び出しで生成されるエラー
このエラーを避けるには、レコード・ポインターをADOレコード・セットの最初のレコードに移動して、その後にUpadateメソッドを呼び出します。具体的には、Updateの呼び出しの前に以下のコードを挿入します。
| |
'Workaround for EOF ADO bug!
If adoRecordSet.RecordCount > 0 Then
adoRecordSet.MoveFirst
End If
|
古いDB2レコードを削除する
テーブルからレコードを削除する手順は、レコードを更新する手順とほぼ同じです。行の列値を変更する代わりに、行を削除するという点が異なるというだけです。行を削除するのにもさまざまな方法があります。以下はその一部です。
- SQL DELETEステートメントを使用する
- ADO RecordsetオブジェクトのDeleteメソッドを呼び出す
上述した更新操作の場合と同様に、Recordset削除メカニズムを使用する重要な利点の1つは、通常の場合、表示目的でレコードがすでに照会済みであるという点です。したがって、レコードの削除は、クライアント・マシン上で削除して、更新されたレコード・セットをサーバーに戻すだけです。反対に、DELETEステートメントは、WHERE文節を使って、サーバー側で実行されなければなりません。これは、削除するレコードを再識別する必要があることを意味します。
DELETEステートメントを使って削除する
SQL DELETEステートメントを使ってレコードを削除するには、次の手順が必要です。
- 適正なSQL DELETEステートメントをコマンド・テキストとして持つADO Commandオブジェクトの作成と初期化を行います。削除する行を識別するために必要なWHERE文節の当該列の値を、'?'パラメーター・マーカーを使って定位置パラメーターとして渡すことができます。これにより、同じADOコマンドを使って、複数のレコードを動的に削除することができます。
- 定位置パラメーターの値を、削除するレコードの識別に必要な実際の列の値に設定します。
- ADO CommandオブジェクトのExecuteメソッドを使って、コマンドを実行します。
- パラメーター値をリセットし、削除する各追加行または行のグループについて、コマンドを再実行します。
リスト10にDeleteUsingDeleteサブルーチンのコードを示します。このサブルーチンは、SQL DELETEステートメントを使って、複数行削除を実行します。同じADOコマンドを使って、複数の行または行のグループを削除することができます。
リスト10.BasicADO − DeleteUsingDeleteサブルーチン
| |
Sub DeleteUsingDelete(ByRef adoConnection As ADODB.Connection)
'Create ADO objects
Dim adoCommand As ADODB.Command
On Error GoTo DeleteUsingDelete_ErrHandler
Set adoCommand = New ADODB.Command
With adoCommand
.CommandType = adCmdText
.ActiveConnection = adoConnection
.CommandText = "DELETE FROM BASICADO WHERE tINT = ?"
End With
'Add Parameters to the Command object
Dim adoParm_tINT As Parameter
Set adoParm_tINT = adoCommand.CreateParameter("tINT", _
adInteger, _
adParamInput)
Call adoCommand.Parameters.Append(adoParm_tINT)
'Delete all records having tINT = 1
adoParm_tINT.Value = 1
Call adoCommand.Execute
Set adoCommand = Nothing
Exit Sub
DeleteUsingDelete_ErrHandler:
Call ShowAllErrors(adoConnection)
End Sub
|
ADO Recordsetを使って削除する
ADO Recordsetを使ってレコードを削除するには、次の手順が必要です。
- 表示するレコードのリストとその後に削除するサブセットを保持するため、ADO Commandとその結果のADOレコード・セットを作成します。ADOレコード・セットは、必ずしも削除するレコードのみである必要はありません。
- ADO接続を開きます。
- ADOコマンドを実行し、ADOレコード・セットとして該当する行の初期リストを検索します。Recordset更新が動作するためには、基本キー列を入れる必要があります。
- Findメソッドを使って、ADOレコード・セットに繰り返しアクセスし、削除する各レコードを特定します。
- ADOレコード・セットでDeleteメソッドを呼び出して、レコードを削除します。
- 完了するまで、レコード・セットで繰り返し続行します。
- ADOレコード・セットのUpdateメソッドを呼び出して、複数行削除をDB2テーブルに伝えます。
- ADO接続を閉じます。
リスト11にDeleteUsingRecordsetサブルーチンのコードを示します。このサブルーチンは、ADO Recordsetオブジェクトを使って複数行削除を実行します。
リスト11.BasicADO − DeleteUsingRecordsetサブルーチン
| |
Sub DeleteUsingRecordset(ByRef adoConnection As ADODB.Connection)
'Create ADO objects
Dim adoCommand As ADODB.Command
Dim adoRecordSet As ADODB.Recordset
On Error GoTo DeleteUsingRecordset_ErrHandler
Set adoCommand = New ADODB.Command
With adoCommand
.CommandType = adCmdText
.ActiveConnection = adoConnection
'Delete requires primary key, so need to select tKEY
.CommandText = "SELECT tKEY, tINT, tVARCHAR, tDATE, tTIME, tDECIMAL
FROM BASICADO"
End With
'Create record set
Set adoRecordSet = New ADODB.Recordset
adoRecordSet.Open adoCommand, , adOpenStatic, adLockOptimistic
'Delete all records having tINT = 2 (requires primary key)
Call adoRecordSet.Find("tINT = 2")
While Not adoRecordSet.EOF()
adoRecordSet.Delete
adoRecordSet.MoveNext
Call adoRecordSet.Find("tINT = 2")
Wend
'Workaround for EOF ADO bug!
If adoRecordSet.RecordCount > 0 Then
adoRecordSet.MoveFirst
End If
'Execute the delete
Call adoRecordSet.Update
Set adoRecordSet = Nothing
Set adoCommand = Nothing
Exit Sub
DeleteUsingRecordset_ErrHandler:
Call ShowAllErrors(adoConnection)
End Sub
|
ヒント − 基本キーを入れる
レコード・セットを使って削除を実行するには、照会に基本キー列を入れる必要があります。基本キーを使って、削除の必要なレコードを識別するための基礎となる適正なDELETE
SQLをADOが生成できるようにするためには、これは必須です。
結論
IBM DB2 V8.1 Development Add-In for Visual Basic 6は、n層アプリケーション開発を大幅に簡素化する優れたツールです。この記事では、ADOプログラミングAPIを使って、4つの基本データベース操作である選択(SELECT)、挿入(INSERT)、更新(UPDATE)、削除(DELETE)を実行する方法について説明しました。また、ADOを使って品質の高いDB2アプリケーションを開発するために役立つヒントも紹介しました。
サンプル・アプリケーションのダウンロード
この記事を通して、ADOを使ったDB2アプリケーション開発の実例として、BasicADOというサンプルのVisual Basicアプリケーションから、コードの断片を抜粋して紹介しました。このセクションでは、アプリケーションのダウンロード、セットアップ、および実行手順について説明します。
このアプリケーションは、「現状のまま」で提供され、保証あるいはサポートの約束は一切ありません。アプリケーション・コードの全部、一部を問わず、ご自分のプロジェクトに自由に使用・再配布してください。
BasicADOアプリケーションをダウンロードする
BasicADOアプリケーションは、Visual Basic 6.0プロジェクトです。必要なテーブルを作成するためのDB2スクリプト・ファイルが含まれています。basicado.zipファイルには、次のファイルが入っています。
- BasicADO.vbp − プロジェクト・ファイル
- frmMain.frm − メイン・アプリケーション・フォーム
- modDBUtil.bas − DB2 ADO関数の入ったモジュール
- createtb.bat − createtb.ddl DB2スクリプト・ファイルを実行するためのバッチ・ファイル
- createtb.ddl − SAMPLEに接続し、必要なテーブルを作成するために必要なDB2スクリプト・ファイル
BasicADOアプリケーションのシステム要件は次のとおりです。
- IBM DB2 Universal Database V8.1以降
- IBM DB2 OLE DBプロバイダー(IBMDADB2)
- Microsoft Windows 2000®、XP®またはNT®
- Microsoft Visual Studio V6.0
- MDAC 2.6以上
| 内容 |
ファイル・タイプ |
ファイル・サイズ |
ダウンロード方法 |
| basicado.zip |
ZIP |
7KB |
HTTP または
FTP |
|
BasicADOアプリケーションをセットアップする
BasicADOアプリケーションは、SAMPLEデータベースとともに動作するように構成されていますが、自分のデータベース名でSAMPLEのすべてのインスタンスを変更することができます。関係するファイルには、createtb.ddlとfrmMain.frmが含まれます。
Visual Basicを起動する前に、BasicADOアプリケーション・テーブルを作成するのに必要なスクリプトを実行してください。具体的には、DB2コマンド・ウィンドウを開いて、バッチ・ファイルcreatetb.batを実行するだけです。
Visual Basicを起動する前に、BasicADOアプリケーション・テーブルを作成するのに必要なスクリプトを実行してください。具体的には、DB2コマンド・ウィンドウを開いて、バッチ・ファイルcreatetb.batを実行するだけです。
必要なテーブルを作成したら、Visual Basicを起動し、BasicADO.vbpプロジェクト・ファイルを開きます。
BasicADOアプリケーションを実行する
BasicADOアプリケーションを実行するには、プロジェクトを実行ファイルにコンパイルするか、あるいは、Visual Basicから直接実行します。
アプリケーションを実行後、図1に示したフォームが表示されます。アプリケーションでは、事前に定義された順序でアクションが実行されることを想定しています。したがって、その順序に従って、アクション・ボタンが使用可能または使用不可になります。
- データベースに接続します。
- INSERTを使って挿入します。
- レコード・セットを使って挿入します。
- UPDATEを使って更新します。
- レコード・セットを使って更新します。
- DELETEを使って削除します。
- レコード・セットを使って削除します。
- 切断します。
著者について
 |
Essma Hasin氏は、認定Visual Basic/Cプログラマーであり、Neneva Technologiesの品質保証エンジニアです。Neneva
Technologiesは、IBM DB2 Universal DatabaseとMicrosoft .Netフレームワークを利用した、中小企業向けのカスタム・ソリューションの構築を専門に行うコンサルティング企業です。
Hasin氏の連絡先は、essma@neneva.comです。
|
IBM、DB2およびDB2 Universal Databaseは、IBM Corporationの米国またはその他の国(あるいはその両方)における商標または登録商標です。
Microsoft、Windows、Windows 2000、Windows NTおよびWindows XPは、Microsoft Corporationの米国またはその他の国(あるいはその両方)における登録商標です。
他の会社名、製品名、およびサービス名は、他社の商標またはサービス・マークである場合があります。
IBMの著作権および商標情報
原文はこちら
|