• 検索結果がありません。

Microsoft Word - bde_to_dbexpress.doc

N/A
N/A
Protected

Academic year: 2021

シェア "Microsoft Word - bde_to_dbexpress.doc"

Copied!
16
0
0

読み込み中.... (全文を見る)

全文

(1)

Borland Database

Engineアプリケーシ

ョンのdbExpress

への移行

プロバイド/リゾルブアーキテクチャ

を使用する新しいアプローチ

The Database Group, Inc.

社長 ビル・トッド

I N D E X

Borland dbExpress-新しいビジョン 1 dbExpressアーキテクチャ 1 プロバイド/リゾルブアーキテクチャの機能する仕組み 2 dbExpressアプリケーションの構築 3 Borland Database EngineとdbExpressの比較 11

Borland Database Engineの

SQL Linksアプリケーションの、dbExpressへの移行 12 デスクトップデータベースアプリケーションの dbExpressへの移行 14 まとめ 16 執筆者について 16

Borland

dbExpress-新しいビジョン

過去に行われた複数のデータベースに共通のAPIを作成 する試みは、すべて、何らかの問題を抱えていました。い くつかのアプローチは、それがあまりにもさまざまな処理 を行おうとしたために大規模で低速なものになり、さらに その配布は困難でした。その他に「共通項」を提供するア プローチもありました。これは、結果として一部のデータ ベースの専用機能について開発者のアクセスを拒否するも のでした。さらに、ドライバの記述が複雑になるアプロー チもありました。そのために機能に制限を残したり、低速 だったり、またバクの多いものになりました。Borland dbExpressは、多数のデータベースに共通のAPIを提供する 新しいアプローチに、データの編集および更新のプロセス を容易にするBorlandの実績あるプロバイド/リゾルブア ーキテクチャを結合することにより、これらの問題を克服 しています。本稿では、dbExpressのアーキテクチャとプ ロバイド/リゾルブメカニズムについて調べ、dbExpress コンポーネントを使ってデータベースアプリケーションを 作成する方法を実証します。また、Borland Database Engine を 使 用 す る デ ー タ ベ ー ス ア プ リ ケ ー シ ョ ン を dbExpressに移行するプロセスについて説明します。

dbExpressアーキテクチャ

dbExpressは、次の6つの目標を達成することを意図して 設計されています。 ・ サイズおよびシステムリソースの使用を最小限に抑える ・ 速度を最大化する ・ クロスプラットフォームをサポートする ・ より容易な配布を可能にする ・ ドライバの開発をより容易にする ・ メモリの使用とネットワークトラフィックについて、開発者 により強力な制御手段を提供する

(2)

dbExpressドライバは、その提供機能が非常に限定的であ るため小さくて高速です。各ドライバは、Windowsプラッ トフォーム上では単一のDLLとして、Linuxプラットフォ ーム上では単一の共有オブジェクトライブラリとして実装 されます。dbExpressドライバは、メタデータのフェッチ、 SQLステートメントおよびストアドプロシージャの実行、 結果セットに対する読み取り専用単方向カーソルをサポー トする5つのインターフェースを実装しています。しかし、 dbExpress を DataSetProviderお よびClientDataSet と併 用してBorlandのプロバイド/リゾルブデータアクセス機 能を実装することにより、SQLデータベース内のデータを 利用する多機能で優れた性能、並列処理機能を持つシステ ムを構築できます。

プロバイド/リゾルブアーキテクチャの機能する仕組み

プロバイド/リゾルブアーキテクチャでは、4つのコンポ ーネントを使用することにより、データのアクセスと編集 を可能にしています。まず第1のコンポーネントは、使用す るデータベースのdbExpressドライバへの接続を提供する SQLConnectionです。第2のコンポーネントはdbExpress データセットコンポーネントの1つであり、SQL SELECT ステートメントを実行するか、もしくはストアドプロシー ジャを呼び出すことにより、データを提供します。第3のコ ンポーネントはDataSetProvider、第4のコンポーネントは ClientDataSet で す 。 ClientDataSet を 開 く と 、 ClientDataSetはDataSetProviderにデータを要求します。 DataSetProviderは、クエリまたはストアドプロシージャ コンポーネントを開き、レコードを検索した後、クエリま たはストアドプロシージャコンポーネントを閉じます。そ して、そのレコードをすべての必要なメタデータとともに ClientDataSetに提供します。 ClientDataSetは、表示中および変更中のレコードをメモ リ内に保持します。コードまたはユーザーインターフェー スのいずれかを通じてレコードの追加、削除、更新が行わ れると、ClientDataSetがメモリ内ですべての変更をログに 記録します。データベースを更新するには、ClientDataSet のApplyUpdates メ ソ ッ ド を 呼 び 出 し ま す 。 す る と 、 ApplyUpdatesがこの変更ログをDataSetProviderに送信 します。このプロバイダは、トランザクションを開始した 後、データベースに変更を適用するためのSQLステートメ ントを作成、実行します。プロバイダはすべての変更が正 常に適用された場合にトランザクションをコミットし、そ うでない場合はトランザクションをロールバックします。 データベースの更新が失敗するのは、たとえばトリガによ って強制されたビジネスルールに変更が違反する場合、あ るいは更新対象のレコードを読み取った後、別のユーザー がそのレコードを変更した場合などです。エラーが発生し た場合はトランザクションがロールバックされます。そし て、ClientDataSetのOnReconcileErrorイベントが起動し ます。これにより、エラーの処理方法を制御できます。 プロバイド/リゾルブアーキテクチャの利点 短いトランザクションの有効期間 長いトランザクションは、データベースサーバーにロッ クを保持することを強制します。これは、並列性を低下さ せるとともに、データベースサーバーのリソースを消費し ます。プロバイド/リゾルブアーキテクチャでは、トラン ザクションが存在するのは更新の適用時の瞬間です。これ により、混雑したデータベースサーバー上でリソースの消 費が大幅に減少し、並列性が向上します。 任意の行が編集可能 マルチテーブルジョイン、ストアドプロシージャ、読み 取り専用ビューによって返された行は、直接編集できませ ん。フィールドオブジェクトのProviderFlagsプロパティを 使って更新すべきフィールドを特定し、DataSetProvider のOnGetTableNameイベントを使ってテーブルの名前を 指定することにより、多数の読み取り専用データセットを 容易に編集できます。 高速なソートと検索 ClientDataSetはメモリ内にレコードを保持するので、レ コードを高速にソートできます。メモリ内のソートが低速 すぎる場合でも、設計時または実行時にClientDataSetデー タ上にインデックスを作成できます。このメモリ内のイン デックスにより、データベース内にインデックスを維持す るオーバーヘッドを回避しながら、レコードの表示順序の 変更やレコードの検索をほとんど一瞬に行うことができま す。 自動的な集計情報 ClientDataSetは、Sum(Price)-Sum(Cost)などのように、 定義した複雑な集計計算値を自動的に保持します。任意の フィールドまたはフィールドの組み合わせによって集計計 算をグループ化し、そのグループの合計値を算出できます。 また、Min、Max、Count、Avg(平均値)といった集計計 算も使用できます。 データのサブセットのビュー SQL WHERE構文を使ったフィルタ式により、データベ ースサーバーに対して別のクエリを実行するオーバーヘッ

(3)

ドを避けながら、ClientDataSet内のレコードのサブセット を容易に表示できます。 複数のデータビューを同時に表示 ClientDataSet カ ー ソ ル を 複 製 す る 機 能 に よ り 、 ClientDataSet内の異なるデータサブセットを同時に表示 できます。また、同じデータに異なるソートを適用して表 示することもできます。 サーバーにオーバーヘッドをかけない計算フィールド 設計時に計算フィールドをClientDataSetに追加するこ とにより、計算フィールドをメモリ内のデータセットに含 めることができます。この計算はBorland Delphiまたは C++言語のコンパイル済みコードによって実行されるので、 SQLステートメントの計算列またはストアドプロシージャ で可能な計算と比較してより高速であり、はるかに複雑に なりえます。それでいて、データベースサーバーの記憶域 または計算処理に負荷を課しません。 無制限のレコード数 レコードがメモリ内に保持されることから、操作可能な レコード数に制限が課せられることを予想する人もいるか もしれません。しかし、従来のクライアント/サーバーア プリケーション設計では常に、ネットワークトラフィック とデータベースサーバーの負荷を最小限に抑えるために小 さなレコードセットが選択されたことを考えてください。 非常に多くのレコードを扱う必要がある場合でも、各レコ ードに100バイトを含む10,000個のレコードで、わずか1メ ガバイトのメモリしか必要ないことに注意してください。 それ以上に多くのレコードを扱う必要のあるケースはまれ で す が 、 そ の 場 合 で も 、 ClientDataSet お よ び DataSetProviderに用意されているプロパティとイベント を使用して、一部のレコードをフェッチしてそれを編集し た後、メモリからそれらのレコードを除去して次のレコー ドグループをフェッチすることができます。 より容易な配布 dbExpressを使用するアプリケーションが機能するため に 必 要 と す るDLL は 2 つ だ け で す 。 ま ず 第 1 の DLL は dbExpressドライバです。たとえばBorland InterBaseの場 合ならDBEXPINT.DLLです。第2のDLLは、ClientDataSet サポートライブラリであるMIDAS.DLLです。これら2つの DLLのサイズはともに、0.5メガバイト未満です。これによ りアプリケーションサイズを最小限に抑え、インストール を簡素化できます。これらのDLLを配布したくなければ、 EXE内に直接コンパイルすることもできます。Linux上に 配布する場合でも、DLLが2つの共有オブジェクトライブラ リに置き換わる点を除けば違いはありません。 容易なドライバ生成 dbExpressドライバでは、オンラインヘルプに記載され ている5つのインターフェースを実装する必要があります。 Borlandはまた、Microsoft MySQLドライバのソースコー ドをモデルとして提供しています。これにより、データベ ースベンダーが堅牢な高性能ドライバを容易に作成できま す。さらに、一般的でないデータベースや旧来のデータベ ースを扱う場合で、商用のドライバが使用できないときは、 独自のドライバを作成できます。

dbExpressアプリケーションの構築

既存のBorland Database Engineアプリケーションを dbExpressに変換する前に、dbExpressコンポーネントとそ の 使 用 方 法 に 精 通 す る こ と が 必 要 で す 。 こ こ で は 、 dbExpressアプリケーションを、手順を追って作成しなが ら、使用する各コンポーネントについて説明します。この 例はWindowsプラットフォーム上でBorland Delphiを使 っ て 構 築 し て い ま す が 、Linuxプラットフォーム上で Borland Kylixを使用する場合でもその手順は同じです。 このサンプルアプリケーションでは、InterBaseのサンプ ル で あ るEMPLOYEE.GDB デ ー タ ベ ー ス を 使 用 し 、 EmployeeテーブルとSalary Historyテーブルの間の1対多 関 係 を 表 示 し ま す 。 サ ン プ ル ア プ リ ケ ー シ ョ ン は 、 dbExpressの次の機能を実証します。 ・ マスターテーブル内のフィールドに詳細テーブルをネスト する ・ SQLQuery、DataSetProvider、ClientDataSetの各コンポーネ ントを使ってデータを編集する ・ DataSetProviderおよびClientDataSetを使用しないで、読み 取り専用データセットとしてSQLQueryを使用する ・ ClientDataSet内に含まれる更新をデータベースに適用する ・ 更新をデータベースに適用したときに発生するエラーを処 理する SQLConnectionコンポーネント 簡単なdbExpressアプリケーションを作成するには、ま ず次の手順を実行します。 1. 新しいアプリケーションを作成し、それにデータ モジュールを追加します。このデータモジュール にMainDmという名前を付けます。 2. [Project Options]ダイアログを使って、メイン フォームの作成前にデータモジュールが自動的

(4)

に作成されることを確認します。 3. コンポーネントパレットの[dbExpress]ページ からSQLConnectionコンポーネントをデータモ ジュール上にドロップします。 4. こ の SQLConnection コ ン ポ ー ネ ン ト に EmployeeConnection と い う 名 前 を 付 け 、 DriverNameプロパティにInterBaseを設定しま す。 5. Paramsプロパティのプロパティエディタを開い て、databaseパラメータにサンプルのInterBase EMPLOYEE.GDBデータベースへのパスを設定 します。ほとんどのインストールで、このパスは c:¥program files¥Borland¥interbase¥examples¥dat abase¥employee.gdbになります。 6. 必要に応じて、InterBaseサーバーに接続するた め の 適 切 な 値 をUserNameパ ラ メー タおよ び Passwordパラメータに設定します。 7. プログラムを実行するたびにユーザー名とパス ワードの入力を促されることのないように、 LoginPromptプロパティにfalseを設定します。 8. 接続をテストするためにConnectedプロパティに trueを設定した後、もう一度Connectedプロパテ ィにfalseを設定します。 SQLConnectionコンポーネントは、任意の数のデータセ ットコンポーネントにデータベース接続を提供します。複 数のSQLConnectionコンポーネントを使用することによ り、多数のデータベースに同時に接続できます。データベ ースへの接続を定義するには、既存の名前付き接続を使用 する方法、次に新しい名前付き接続を作成する方法、そし てSQLConnectionコンポーネントのParamsプロパティに 接続パラメータを含める方法の3つの方法があります。既存 の名前付き接続を使用する場合は、ConnectionNameプロ パティを設定するだけで済みます。 dbExpress 接続エディタ 新しい名前付き接続を作成するには、[SQLConnection コンポーネント]をダブルクリックし、dbExpress接続エ ディタを開きます。左側の[Connection Name]リストボ ックスには、既に定義済みの接続がすべて表示されます。 [Driver]ドロップダウンリストでドライバを選択するこ とにより、そのドライバに対応する接続のみを[Connection Name]に表示するようにフィルタをかけることができま す。右側の[Connection Settings]グリッドには、選択し た接続の接続設定が表示されます。作成した接続はすべて、 dbxconnections.iniファイルに格納されます。 接続エディタ 接続ファイル 名前付き接続を作成した後、それをSQLConnectionの ConnectionNameプロパティに割り当てます。名前付き接 続を使用する場合、アプリケーションとともに接続ファイ ルを配布するか、あるいはターゲットコンピュータ上で既 存の接続ファイルを確認し、それに接続を追加する必要が あります。 SQLConnection コンポーネントの Params プロパティ もう1つの方法では、まずSQLConnectionコンポーネン トのDriverNameプロパティを設定します。DriverName プロパティのドロップダウンリストには、システム上にイ ンストールされたすべてのドライバが表示されます。この ドライバの情報は、dbxdrivers.iniファイルに含まれていま す。DriverNameプロパティを設定すると、このドライバ ファイルからの情報に基づいて、LibraryNameプロパティ とVendorLibプロパティも設定されます。LibraryNameに は、dbExpressドライバDLLの名前が含まれます。また VendorLibには、データベースベンダーのクライアントラ イブラリファイルの名前が含まれます。 上記の図のように、接続エディタからSQLConnectionコ ンポーネントのParamsプロパティに接続パラメータを入 力します。この方法により、すべての接続情報をアプリケ ーションに含めることができます。アプリケーションユー ザーに接続パラメータを変更することを許可する場合は、 その接続パラメータをアプリケーション独自の構成ファイ ルに格納し、そのファイルを編集する手段をアプリケーシ ョン内または別個の構成プログラムのいずれかに用意しま す。これにより、各アプリケーションは完全に「自己完結 的」なものになります。 SQLConnectionコンポーネントはまた、明示的なトラン ザクション制御を行うために、StartTransactionメソッド、 Commitメソッド、Rollbackメソッドを提供しています。結

(5)

果セットを返さないSQLステートメントを実行する必要が ある場合は、SQLConnectionコンポーネントのExecuteメ ソッドまたはExecuteDirectメソッドを使用できます。デー タセットコンポーネントは必要ありません。作業中のデー タベースのメタデータにアクセスする必要がある場合は、 SQLConnection の 提 供 す る GetTableNames メ ソ ッ ド 、 GetFieldNamesメソッド、GetIndexNamesメソッドを使 用できます。 DataSetコンポーネント

dbExpress は 、 SQLDataSet 、 SQLQuery 、 SQLStoredProc、SQLTableの4つのデータセットコンポー ネントを提供しています。SQLDataSetは、新たに記述す るすべての新しいアプリケーションで選択すべきコンポー ネントです。SQLDataSetのCommandTypeプロパティを 設定することにより、SQLステートメントの実行、ストア ドプロシージャの呼び出し、テーブル内のすべての行およ び列へのアクセスを行うことができます。その他の3つのデ ータセットコンポーネントは、相当するBorland Database Engineのコンポーネントに可能な限り似た機能を持たせ ることを意図して設計されたものです。これらのコンポー ネントを使用することにより、Borland Database Engine アプリケーションをdbExpressにより容易に移行できます。

SQLQuery コンポーネント

SQLQueryコンポーネントのプロパティおよびメソッド は、Borland Database Engine Queryコンポーネントによ く似ています。SQLQueryは読み取り専用の単方向の結果 セットを返すので、Borland Database Engineまたはデー タ編集に関係するプロパティとメソッドは存在しません。 DML お よ び DDL の い ず れ の ス テ ー ト メ ン ト で も 、 SQLQueryを使ってSQLを実行できます。結果セットへの カーソルを返すステートメントの場合は、SQLQueryの Openメソッドを呼び出すか、あるいはSQLQueryのActive プロパティにtrueを設定します。カーソルを返さないステ ートメントの場合は、ExecSQLメソッドを呼び出します。 次の手順に従ってサンプルアプリケーションの構築を続け ます。 1. 3つのSQLQueryコンポーネントをデータモジュ ールにドロップします。 2. 3 つ の コ ン ポ ー ネ ン ト す べ て で 、 そ の SQLConnection プ ロ パ テ ィ に EmployeeConnectionを設定します。 3. 第1のコンポーネントにEmployeeQry、第2のコン ポーネントにHistoryQry、第3のコンポーネントに DeptQryという名前を付けます。 4. EmployeeQryのSQLプロパティを次のように設定 します。

SELECT * FROM EMPLOYEE WHERE DEPT_NO = :DEPT_NO ORDER BY LAST_NAME

5. HistoryQryのSQLプロパティを次のように設定し

ます。

SELECT * FROM SALARY_HISTORY WHERE EMP_NO = :EMP_NO

6. DeptQryのSQLプロパティを次のように設定しま

す。

SELECT DEPT_NO, DEPARTMENT FROM DEPARTMENT ORDER BY DEPARTMENT 7. データモジュールにDataSourceをドロップし、 DataSourceの名前にEmpLinkSrcを設定します。 ま た 、DataSource の DataSet プ ロ パ テ ィ に EmployeeQryを設定します。 8. HistoryQry の DataSource プ ロ パ テ ィ に EmpLinkSrcを設定します。 9. EmployeeQryに戻り、Paramsのプロパティエディ タを開いて、DEPT_NOパラメータの値にXXXを 設定します。この値は無効であるため、ユーザー が有効な部門番号を入力するまでレコードは表示 されません。 10. EmployeeQryをダブルクリックしてFields Editor を開き、すべてのフィールドのフィールドオブジ ェクトを追加します。 11. EMP_NOフィールドを選択してProviderFlagsプ ロパティを展開し、pfInKeyにtrueを設定します。 pfInKeyフラグを設定することにより、EMP_NO フィールドがプライマリキーとして識別されます。 後の手順で追加するDataSetProviderでは、データ ベースに変更を適用するSQLステートメントを構 築するためにこの情報を必要とします。 12. FULL_NAME フ ィ ー ル ド を 選 択 し 、 そ の ProfiderFlagsプロパティを展開します。次に、 pfInUpdateおよびpfInWhereにfalseを設定しま す。FULL_NAMEは計算フィールドです。したが って、DataSetProviderによって生成されるどの SQL ス テ ー ト メ ン ト の WHERE 句 で も 、 FULL_NAMEを更新したりそれを含めたりすべ きではありません。

(6)

SQLStoredProcを使用するには、そのSQLConnectionプ ロパティにSQLConnectionコンポーネントを設定します。 そ し て 、 実 行 す る ス ト ア ド プ ロ シ ー ジ ャ の 名 前 を SQLStoredProcのStoredProcNameプロパティに設定しま す。ストアドプロシージャが行セットを指すカーソルを返 す場合は、SQLStoredProcのActiveプロパティにtrueを設 定するか、あるいはSQLStoredProcのOpenメソッドを呼び 出すことにより、そのストアドプロシージャを実行します。 ストアドプロシージャが結果セットを指すカーソルを返さ ない場合は、ExecProcメソッドを呼び出すことによりスト アドプロシージャを実行します。 13. EmployeeQryのActiveプロパティにtrueを設定し ます。 14. HistoryQryをダブルクリックしてFields Editorを 開き、すべてのフィールドオブジェクトを追加し ます。 15. Fields EditorでEMP_NOフィールドを選択し、 ProviderFlagsプロパティ内でpfInKeyにtrueを設 定します。また、同様にプライマリキーの一部で あ る CHANGE_DATE フ ィ ー ル ド と UPDATER_IDフィールドにも同じ操作を繰り返 します。 SQLDataSet 16. NEW_SALARYフィールドも計算フィールドであ るため、NEW_SALARYフィールドを選択し、そ のProfiderFlagsプロパティでpfInUpdateおよび pfInWhereにfalseを設定します。 SQLDataSetを使用するには、そのSQLConnectionプロ パティに、使用するSQLConnectionコンポーネントを設定 しま す。次に、CommandTypeプロパティにctQuery、 ctStoredProc、またはctTableを設定します。最も一般的に は 、 デ フ ォ ル ト 値 で あ るctQuery が 使 用 さ れ ま す 。 CommandTextプロパティの値は、CommandTypeの値に 依 存 し ま す 。CommandType が ctQuery で あ る 場 合 、 CommandTextには実行するSQLステートメントを含めま す 。CommandType が ctStoredProc で あ る 場 合 は 、 CommandText は ス ト ア ド プ ロ シ ー ジ ャ の 名 前 で す 。 CommandTypeがctTableである場合は、CommandTextは テーブルの名前です。「パラメータ化」クエリまたはスト アドプロシージャにパラメータを提供するにはParamsプ ロパティを使用し、SQLDataSetを別のデータセットコン ポ ー ネ ン ト に マ ス タ ー / 詳 細 関 係 で 接 続 す る に は DataSourceプロパティを使用します。SQLDataSetが1セ ッ ト の レ コ ー ド を 指 す カ ー ソ ル を 返 す 場 合 は 、 SQLDataSetのOpenメソッドを呼び出すか、あるいは Activeプロパティをtrueに設定することによりそれを開き ま す 。SQLDataSet が 結 果 セ ッ ト を 返 さ な い 場 合 は 、 SQLDataSetのExecSQLメソッドを呼び出します。 17. EmployeeQryおよびHistoryQryのActiveプロパ ティにfalseを設定します。 18. EmployeeConnectionのConnectedプロパティに falseを設定します。 SQLTable

SQLTableは、Borland Database EngineのTableに似た コンポーネントです。相当するBorland Database Engine のコンポーネントであるTableと同じように、SQLTableは テーブル内のすべての行および列を返すので、クライアン ト/サーバーアプリケーションには適していません。その 唯一の利点は、BDE Tableコンポーネントを使用するデス ク ト ッ プ デ ー タ ベ ー ス ア プ リ ケ ー シ ョ ン を 短 時 間 で dbExpressおよびデータベースサーバーに移行できること です。 SQLTableを使用するには、そのSQLConnectionプロパ ティにSQLConnectionコンポーネントを設定します。そし てTableNameプロパティに、アクセスするテーブルの名前 を設定します。Activeプロパティにtrueを設定するか、あ るいはOpenメソッドを呼び出すことによりテーブルを開 きます。 SQLDataSetは、読み取り専用の単方向カーソルのみを 提供します。これが唯一の必要なアクセス方式である場合、 た と え ば レ ポ ー ト を 印 刷 す る よ う な と き に は 、 SQLDataSetを単独で使用するか、あるいはレポーティン グツールの要件に応じてDataSourceコンポーネントと併 用できます。レコードを前後にスクロールする必要がある 場合、またはデータを編集する必要がある場合には、本稿 で 後 ほ ど 説 明 す る よ う に 、DataSetProvider お よ び ClientDataSetを追加するか、SimpleDataSetコンポーネン トを使用します。 The SQLStoredProc

Borland Database Engine ア プ リ ケ ー シ ョ ン で BDE StoredProcコンポーネントを使用するのと同じ方法で、 SQLStoredProcコンポーネントを使ってストアドプロシー ジャを呼び出します。また、SQLDataSetコンポーネント を使ってストアドプロシージャを呼び出すこともできます が、SQLStoredProcコンポーネントはBDE StoredProcコン ポーネントとほとんど同じであるため、SQLStoredProcコ ンポーネントを使ってBorland Database Engineアプリケ ーションを移行した方がより簡単です。

SQLConnectionメソッドが提供するよりも詳細なメタ データ情報を必要とする場合は、SQLDataSetコンポーネ ン ト のSetSchemaInfo メ ソ ッ ド を 使 用 し ま す 。 SetSchemaInfo は 3 つ の パ ラ メ ー タ SchemaType 、

(7)

SchemaObject、SchemaPatternを取ります。SchemaType は 、stNone 、 stTables 、 stSysTables 、 stProcedures 、 stColumns、stProcedureParams、stIndexesのいずれかで す 。 こ の パ ラ メ ー タ は 、SQLDataSet を 開 い た と き に SQLDataSetに含まれる情報のタイプを示しています。こ のスキーマタイプには、SQLステートメントまたはストア ドプロシージャを使ってテーブルからデータを検索する場 合に、stNoneを設定します。その他の各スキーマタイプで は、返される情報に応じた適切な構造を持つデータセット が作成されます。SchemaObjectには、ストアドプロシージ ャ名またはテーブル名が必要な場合に、ストアドプロシー ジャかテーブルの名前を指定します。SchemaPatternには、 結果セットにフィルタをかけるSQLパターンを指定します。 たとえば、SchemaTypeがstTablesで、SchemaPatternが 'EMP%'である場合、データセットには先頭にEMPの付く テーブルだけが含まれます。 SimpleDataSet

Borland Database Engineを使って1つのレコードセッ トを表示および編集する場合に実行する必要があるのは、 データモジュールにTQueryをドロップし、2つのプロパテ ィを設定することだけです。dbExpressでは、データモジ ュ ー ル に SQLQuery ま た は SQLDataSet と 、 DataSetProviderおよびClientDataSetをドロップし、それ らを合わせて接続するようにプロパティを設定する必要が あります。さほど時間をかけないで3つのコンポーネントを 追加し、そのプロパティを設定する方法が2つあります。

Borland Delphi 7 Studioには、SimpleDataSetコンポー ネ ン ト が 導 入 さ れ て い ま す 。SimpleDataSet は 、 SQLDataSet、DataSetProvider、ClientDataSetを単一の コンポーネント内にまとめています。単一のテーブルまた はストアドプロシージャのレコードを表示、編集すること だけが必要な場合は、SimpleDataSetが簡単なソリューシ ョンです。データモジュールにSimpleDataSetを追加し、 ConnectionプロパティにSQLConnectionコンポーネント を設定します。さらに、組み込まれたSQLDataSetコンポ ーネントのCommandTypeプロパティとCommandTextプ ロパティを設定すれば、作業は完了です。SimpleDataSet コンポーネントには、次のような制限があります。 ・ 多層アプリケーション内では使用できません。将来、多層ア プリケーションに移行する可能性がある場合は、個別のコン ポーネントを使用してください。 ・ 子データセットを、ネストしたデータセットフィールドとし てSimpleDataSetに接続できません。 ・ 内部のDataSetProviderのどのイベントも通知されません。 ・ 内部のDataSetProviderのOptionsプロパティは公開されま せん。設計時または実行時にプロバイダオプションを設定す ることはできません。 ・ 内部データセットのフィールドオブジェクトのインスタン スを設計時に作成することはできません。つまり、フィール ドオブジェクトのProviderFlagsプロパティを設計時に設定 できないことを意味します。この処理はコード内で行う必要 があります。 ・ ClientDataSetコンポーネントの内部データベースとして Borland MyBaseのみを使用する場合で、データベースサー バーに接続せず、ClientDataSetだけを使用するときは、アプ リケーションのリソース要件が軽減されます。 ・ 組 み 込 み のSQLDataSet の プ ロ パ テ ィ と メ ソ ッ ド に は 、 SQLQueryの場 合とは異なり、Borland Database Engine Queryコンポーネントのプロパティとメソッドとの類似性は あ り ま せ ん 。 し た が っ て 、 移 行 プ ロ ジ ェ ク ト 内 で SimpleDataSetを使用すると、必要なコード変更量が増大す る可能性があります。 SimpleDataSetよりも高い柔軟性を必要とする場合は、 SQLQuery、DataSetProvider、およびClientDataSetをフ ォームまたはデータモジュールにドロップします。次に、 SQLQueryのConnectionプロパティを設定します。そして、 DataSetProviderのDataSetプロパティを設定してそれを SQLQuery に 接 続 し ま す 。 さ ら に 、 ClientDataSet の ProviderName プ ロ パ テ ィ を 設 定 し て そ れ を DataSetProviderに接続します。3つのコンポーネントすべ てを選択し、メインメニューから[Component | Create Component Template]を選択します。新しいテンプレー トのクラス名とパレットページを設定します。これで、あ たかも単一のコンポーネントをドロップするかのように3 つの別個のコンポーネントを簡単にデータモジュールにド ロップできるようになります。 SQL Monitor 最 後 に 取 り上げ るdbExpressコンポーネントBorland SQL Monitorは、アプリケーションのパフォーマンスを調 整 す る た め に 役 立 ち ま す 。SQL Monitor は 、 SQLConnectionコンポーネントと、その接続先であるデー タベースサーバー間でやり取りされるSQLステートメント をすべてチェックします。このSQLステートメントは、そ のログをファイルに記録したり、メモコンポーネントに表 示したりすることができます。さらに、必要に応じてその 他の方法で自由に処理できます。 データアクセスコンポーネント 双方向のスクロールやデータの更新を必要とする場合は、 DataSetProviderコンポーネントとClientDataSetコンポ ーネントを使用する必要があります。

(8)

DataSetProvider DataSetProviderは、そのDataSetプロパティを通じて、 いずれかのdbExpressデータセットコンポーネントに接続 します。DataSetProviderは要求に応じてClientDataSetに データを提供し、ClientDataSetから提供された変更ログを もとにデータベースを更新するSQL DMLステートメント を生成します。 サンプルアプリケーションのデータモジュールに戻り、 次の手順を実行してください。 1. コンポーネントパレットの[Data Access]ページか らDataSetProviderを追加します。 2. そのDataSetプロパティにEmployeeQryを設定し、 NameプロパティにEmployeeProvを設定します。 DataSetProviderのUpdateModeプロパティは、更新対象 のレコードを読み取った後、別のユーザーによってレコー ドが更新されているかどうかプロバイダが判別する方法を 制御します。プロバイダがデータベースを更新するSQLス テートメントを生成すると、各UPDATEステートメントお よびDELETEステートメントには、レコードを識別する WHERE句が含まれます。UpdateModeをupWhereAllに設 定 し た 場 合 、 レ コ ー ド 内 の フ ィ ー ル ド の う ち 、 そ の pfInWhereプロバイダフラグがfalseでないすべての非Blob フィールドの元の値がWHERE句に含まれます。つまり、 別のユーザーがこれらのフィールドのうちのいずれかを変 更した場合、UPDATEまたはDELETEは失敗することにな ります。UpdateModeにupWhereChangedを設定すると、 自分が変更したフィールドだけがWHERE句に含まれます。 UpdateModeにupWhereKeyOnlyを設定した場合は、プラ イマリキーフィールドのみを含むWHERE句が生成されま す。 プロバイダのOptionsプロパティには、プロバイド/リゾ ルブプロセスを制御するための多数のフラグが含まれてい ます。poCascadeDeletesオプションにtrueを設定した場合、 プロバイダは削除したマスターレコードの詳細レコードを 削除するSQLステートメントを生成しません。この場合プ ロバイダは、データベースサーバーでカスケード削除機能 がサポートされていて、詳細レコードが自動的に削除され ることを想定します。poCascadeUpdatesオプションは、 マスターテーブルのプライマリキーの変更について、同様 の機能を提供します。 プロバイダにデータを提供するSQLQueryのSQLステー トメントにORDER BY句が含まれていて、ClientDataSet 内 で レ コ ー ド の 順 序 を 維 持 す る 場 合 は 、 poRetainServerOrder フ ラ グ に true を 設 定 し ま す 。 ClientDataSetのCommandTextプロパティを変更するこ とによりSQLQueryのSQLステートメントを変更できるよ うにする場合は、poAllowCommandTextオプションにtrue を設定します。 DataSetProviderのBeforeUpdateRecordイベントハン ドラを作成し、そのイベントハンドラでデータベースの更 新前にレコード内のフィールド値を変更する可能性がある 場合は、poPropogateChangesオプションにtrueを設定しま す。これでプロバイダは、メモリ内に保持するレコードを 更新するためにすべての変更をClientDataSetに送り返し ます。 DataSetProviderは多数の有用なイベントを持ちますが、 最 も 重 要 な2 つ の イ ベ ン ト は OnGetTableName と BeforeUpdateRecordです。マルチテーブルジョイン、スト アドプロシージャ、読み取り専用ビューによって返された 行は、データベースアプリケーション内で直接編集できま せん。 DataSetProviderは、このような状況に対処するための3 つのツールを提供しています。レコードに単一テーブルの フィールドが含まれる場合(たとえばストアドプロシージ ャによって返されたレコードなど)、唯一問題になるのは DataSetProviderが更新すべきテーブルの名前を把握する 手段を持たないことです。解決策は、そのテーブル名を返 す、DataSetProviderのOnGetTableNameイベントハンド ラを作成することです。 第2に考慮すべき状況は、単一テーブルのフィールドを更 新する必要があるマルチテーブルジョインです。まず、個々 のフィールドのProviderFlagsプロパティを設定し、更新す べきフィールドを識別します。次に、テーブル名を返す OnGetTableNameイベントハンドラを作成します。これに より、プロバイダがSQLステートメントを自動的に生成し ます。各レコードで複数のテーブルを更新する必要がある 場 合 は 、BeforeUpdateRecord イ ベ ン ト ハ ン ド ラ を DataSetProviderに追加します。そしてこのイベントハン ドラ内で、各テーブル用のSQLステートメントを生成し、 それを実行できます。 BeforeUpdateRecordイベントハンドラ内では、各レコー ドを更新前に調査し、任意のフィールド値を変更できます。 さらに、例外を発生させることにより、更新を完全に阻止 することもできます。これにより、BeforeUpdateRecord はビジネスルールを強制するために適した場所になってい ます。 ClientDataSet コンポーネント ClientDataSetは、そのProviderNameプロパティを通じ てDataSetProviderに接続します。ClientDataSetは、対応 するDataSetProviderからデータを受信し、そのデータを メモリ内のバッファに入れます。そして、データへの変更

(9)

をすべてログに記録し、ClientDataSetのApplyUpdatesメ ソッドが呼び出されたときにDataSetProviderに変更ログ を送信します。 次の手順に従ってサンプルアプリケーションの構築を続 けます。 1. サンプルアプリケーションのデータモジュールに 2つのClientDataSetsをドロップします。 2. 最初のClientDataSetsのProviderNameプロパテ ィにEmployeeProvを設定し、Nameプロパティに EmployeeCdsを設定します。 3. EmployeeCdsをダブルクリックしてFields Editor を開き、すべてのフィールドオブジェクトを追加し ます。Fields Editor内で、最後のフィールドオブ ジェクトにHistoryQryという名前を付けます。こ れはネストしたデータセットフィールドであり、各 従業員レコードに対応する給与履歴レコード群を 含みます。HistoryQryコンポーネントによって返 されるレコードは、EmployeQry結果セット内でネ ストしたデータセットとして表示されます。それは、 SQLClientDataSets の HistoryQry の DataSource プ ロ パ テ ィ にEmpLinkSrcが設定されていて、 EmpLinkSrc が EmployeeQry に 接 続 し 、 さ ら に EmpLinkSrcがそのSQLステートメントに対する パラメータ値をEmployeeQryレコードから取得す るためです。 4. EmployeeCdsを右クリックしてショートカットメ ニューから[Fetch Params]を選択します。これ により、ClientDataSetがそのパラメータリストを EmployeeQryコンポーネントに一致するように更 新します。 5. 第2のClientDataSetにHistoryCdsという名前を付 け 、 そ の DataSetField プ ロ パ テ ィ に EmployeeCdsHistoryQryを設定します。これによ り、HistoryCdsがEmployeeCds内のネストしたデ ータセットフィールドからデータを取得します。 6. HistoryCdsをダブルクリックし、すべてのフィー ルドを追加します。 7. データモジュールに2つのDataSourceコンポーネ ントをドロップし、それぞれにEmployeeSrcおよ びHistorySrcという名前を付けます。 8. それぞれのDataSetプロパティにEmployeeCdsお よびHistoryCdsを設定します。 こ れ に よ り 、EmployeeCds コ ン ポ ー ネ ン ト お よ び HistoryCdsコンポーネントのActiveプロパティにtrueを設 定できるはずです。データモジュールは次の図のようにな ります。 データモジュールの図 ネストした詳細データセットは非常に効果的です。これ は、マスターデータセットと詳細データセットの更新の適 用順序について、混乱を回避できるためです。たとえば、1 つ以上の詳細レコードを含む新しいマスターレコードを追 加した場合、マスターレコードのINSERTステートメント が詳細レコードのINSERTステートメントより前にデータ ベースサーバーに送信されるはずです。しかし、マスター の詳細レコードを削除した後、マスターレコードを削除す る場合は、詳細レコードのDELETEステートメントをマス ターのDELETEステートメントの前に処理する必要があ ります。DataSetProviderは、ネストしたデータセットに 対して、データベースサーバーのエラーを回避する正しい 順序で更新を処理することを保証します。 ClientDataSetはいくつかの有用なプロパティを持ちま す。Aggregatesプロパティは、データセット内の数値フィ ールドの合計値、最小値、最大値、カウント、平均値を自 動的に計算、維持する集計フィールドを定義します。この 集計値は、任意のインデックスによってグループ化できま す。AggregatesActiveプロパティにより、実行時に集計計 算を有効または無効にできます。IndexFieldNamesプロパ ティにセミコロンで区切ったフィールド名のリストを割り 当てることにより、そのフィールドによってClientDataSet 内のレコードを昇順にソートできます。降順にソートする 場合、または非常に大規模なデータセットでソートを高速 化する場合は、ソートの基準とするフィールドに対するイ ンデックスを作成し、そのインデックス名をClientDataSet のIndexNameプロパティに割り当てます。 CommandText プ ロ パ テ ィ を 使 う こ と に よ り 、 DataSetProviderにデータを提供するコンポーネント内の SQLステートメントを変更します。ClientDataSetを閉じ、

(10)

新しいSQLステートメントをCommandTextに割り当て、 ClientDataSetを開けば、新しいクエリによって返されたレ コードを見ることができます。また、ClientDataSetの Paramsプロパティを使って、ソースデータセットのSQL ステートメント内のパラメータに新しい値を割り当てるこ ともできます。ソースデータセットのプロパティに直接ア クセスするのではなく、ClientDataSetのCommandText プロパティとParamsプロパティを使用しなければならな い理由は何でしょうか。この利点は、将来プログラムを多 層Borland DataSnapアプリケーションに変換する場合に、 コードを変更する必要がなくなることです。 Action := HandleReconcileError( DataSet, UpdateKind, E);

ユーザーが更新を適用したときにエラーが発生した場合、 Reconcile Error Dialogが開き、エラーメッセージ、エラー の原因となったレコード、ユーザーがエラーの対処方法を 選択する一連のボタンが表示されます。サンプルアプリケ ーションを完成するために、次の手順に従います。 1. メインフォームに2つのパネル、2つのDBGrids、 および2つのDBNavigatorsを追加し、次の図のよ うに配置します。 PacketRecordsプロパティは、プロバイダがサーバーか ら一度にフェッチするレコード数を制御します。デフォル ト値の-1は、ソースデータセットのSQLステートメントに よって返されたすべてのレコードをフェッチするようにプ ロバイダに指示します。通常はこの設定でうまく機能しま すが、非常に多数のレコードを処理する場合は、小さなグ ループでレコードを検索する必要があります。 dbExpressのプロバイド/リゾルブアーキテクチャと Borland Database Engineの最も大きな相違の1つは、変更 ロ グ 内 の 変 更 を デ ー タ ベ ー ス に 適 用 す る た め に ClientDataSetのApplyUpdatesメソッドを呼び出す必要が あることです。ChangeCountプロパティを使って、未適用 の変更が変更ログ内に存在するかどうか判別します。 ApplyUpdatesは、許容エラー数を指定する単一のパラメー タを取ります。このエラー数を超えると、更新プロセスが 中止され、トランザクションがロールバックされます。一 般的には、このパラメータには0が指定されます。この場合、 エラーが発生するとすぐに、更新プロセスが終了します。 -1を指定すると、発生したエラーの数にかかわらず、変更 ログ内のすべての変更を適用するようにDataSetProvider に指示します。 2. データモジュールユニットをフォームユニットの uses句に追加します。 3. 上側のDBGridおよびDBNavigatorのDataSource プロパティにEmployeeSrc DataSourceコンポー ネントを設定します。 4. 下側のDBGridおよびDBNavigatorのDataSource プロパティにHistorySrc DataSourceコンポーネ ントを設定します。 更 新 エ ラ ー が 発 生 す る と 、 ClientDataSet の OnReconcileErrorイベントが起動します。デモアプリケー ション内で更新エラーを処理するには、次の手順を実行し ます。 5. 上 側 の パ ネ ル にLabel コ ン ポ ー ネ ン ト お よ び ComboBoxコンポーネントを追加します。 6. ComboBoxのOnChangeイベントハンドラを作成 し、次のコードを追加します。 1. Object Repository の [ Dialogs ] ペ ー ジ か ら 、

Reconcile Error Dialogをプロジェクトに追加しま す。

procedure TMainForm.DeptComboChange( Sender: TObject);

begin

with MainDm.EmployeeCds do begin

if Active then CheckBrowseMode; Close; Params.ParamByName('DEPT_NO').AsString := Copy(DeptCombo.Text, 1, 3); Open; end; //with end;

2. デ ー タ モ ジ ュ ー ル のuses 句 に Reconcile Error Dialogユニットを追加します。

3. Reconcile Error Dialogが自動的に作成されないこ とを確認します。

4. EmployeeCdsのOnReconcileエラーイベントハン ドラを作成し、次のコード行を追加します。

(11)

7. 上側のパネルにButtonコンポーネントを追加し、

そのキャプションにSave Changesを設定します。 procedure TMainForm.LoadDeptCombo; begin

with MainDm do begin

DeptQry.Open; while not DeptQry.Eof do begin DeptCombo.Items.Add( 8. ButtonのOnClickイベントハンドラに次のコード を追加します。 procedure TMainForm.SaveBtnClick(Sender: TObject); begin with MainDm do begin if EmployeeCds.ChangeCount > 0 then Begin if HistoryCds.Active then HistoryCds.CheckBrowseMode; if EmployeeCds.Active then EmployeeCds.CheckBrowseMode; EmployeeCds.ApplyUpdates(0); EmployeeCds.Refresh; end; //if end; //with end; DeptQryDept_No.AsString + ‘ ‘ + DeptQryDepartment.AsString); DeptQry.Next; end; //while DeptQry.Close; end; //with end; 10. フォームに次のOnCreateイベントハンドラを追加 します。 Procedure TmainForm.FormCreate(Sender: Tobject); begin MainDm.EmployeeCds.Open; LoadDeptCombo; end; 9. 部門のComboBoxにデータを格納するメソッドを 追加します。

Borland Database EngineとdbExpressの比較

次 の 表 は 、 重 要 な い く つ か の 分 野 に つ い てBorland Database EngineとdbExpressを比較し、両者の相違につ いてその概要を示しています。2番目の表は、各Borland Database Engine コン ポーネント と、それに相 当す る dbExpressコンポーネントを示しています。 機能 Borland Database Engine dbExpress レコード のバッフ ァリング

Borland Database Engine がローカルメモリのバッファ に入れるレコード数を決定し ます。 開発者がローカルバッファ に入れるレコード数を制御 できます。 ネットワ ークトラ フィック制 御

Borland Database Engine がサーバーからフェッチする レコード数を決定します。 開発者がサーバーからフ ェッチするレコード数とそ の時期を制御します。 トランザ クション 制御 手動および自動のトランザ クション制御がともに使用可 能です。ユーザーがデータ を編集している間、トランザ クションはアクティブです。 自動および手動のトラン ザクション制御がともに使 用可能です。トランザクシ ョンは、更新が適用される 非常に短い時間、アクティ ブになります。 配布 配布は大規模です(約18メ ガバイト)。インストールと構 成は複雑であり、レジストリ 配布に必要なのは2つの DLLで、その合計は0.5メ ガバイト未満です。これら の変更が必要です。 のDLLはEXE内にコンパ イルできます。 dbxconnections.iniファイ ルとdbxdrivers.iniファイル を配布しない限り、レジス トリの変更は必要ありませ ん。 クロスプ ラットフォ ーム性 Windowsのみ WindowsおよびLinux サードパ ーティド ライバ 開発は困難です。使用可能 なドライバは少数です。 開発は容易です。多数の ドライバが使用可能です。 サードパーティ製ドライバ の詳細については、 Borland Developer Network Webサイト (bdn.Borland.com)を参 照してください。

次の表は、各Borland Database Engineコンポーネント

に相当するdbExpressコンポーネントを示しています。

Borland Database Engine BatchMoveコンポーネントに 相当するdbExpressのコンポーネントは存在しないことに 注意してください。

(12)

Borland Database Engine dbExpress Tdatabase TSQLConnection TQuery TSQLQuery TStoredProc TSQLStoredProc TTable TSQLTable 相当コンポーネントはありません TSQLDataSet TBatchMove 相当コンポーネントはありません SQL Monitor Utility TSQLMonitor

Session 対象外 UpdateSQL 対象外 NestedDataSet 対象外

BDEClientDataSet SimpleDataSet

dbExpressにはセッションの概念が存在しません。した がって、Borland Database Engineセッションコンポーネ

ントに相当するコンポーネントは必要ありません。Borland

Database Engine UpdateSQLコンポーネントが使用され るのは、Borland Database Engine Queryコンポーネント のキャッシュ更新機能とともに併用される場合に限られま す。dbExpressでは、キャッシュ更新機能はClientDataSet コンポーネントの機能に置き換えられました。dbExpress のDataSetProviderコンポーネントとClientDataSetコン ポーネントには、ネストしたデータセットを扱うための機 能が組み込まれています。

Borland

Database EngineのSQL Linksアプリケーションの、dbExpressへの移行

Borland Database EngineおよびSQL Linksドライバを 使用するアプリケーションをdbExpressに移行するには、 次の手順が必要です。大半のクライアント/サーバーアプ リケーションは、Borland Database Engine Tableコンポ ーネントを使用しません。デスクトップデータベースアプ リケーションではBorland Database Engine Tableコンポ ーネントが広範に使用されるので、このコンポーネントに ついては、本稿の「デスクトップデータベースアプリケー ションのdbExpressへの移行」で後ほど説明します。

・ Borland Database Engine データベースコンポーネントを SQLConnectionコンポーネントに置き換えます。 ・ Borland Database Engine の Query コ ン ポ ー ネ ン ト と

StoredProcコンポーネントをSQLQueryコンポーネントと SQLStoredProcコンポーネントに置き換えます。 ・ 双方向のスクロールまたは編集処理が必要な場合は、各

SQLQueryコンポーネントおよびSQLStoredProcコンポーネ ントにDataSetProviderおよびClientDataSetを追加します。

Borland Database EngineデータベースのSQLConnection

への置き換え

各Borland Database Engineデータベースコンポーネン トをSQLConnectionコンポーネントに置き換える必要が あります。 接続パラメータの設定 アプリケーションを変更しないで、Borland Database Engineエイリアスを使ってデータベース接続を変更する には、dbExpressの名前付き接続を使用するか、あるいは INIファイルに接続パラメータを格納する必要があります。 最も柔軟で堅牢な方法は、アプリケーション固有のINIファ イルを使って接続パラメータを保持することです。この方 法を選択する場合は、アプリケーションの起動時にINIファ イ ル を 読 み 取 り 、SQLConnection コ ン ポ ー ネ ン ト の Paramsプロパティを設定するコードをアプリケーション に追加する必要があります。また、ユーザーによるINIファ イル内の接続パラメータの編集を可能にするコードをアプ リケーションに追加することもできます。 トランザクションの制御 アプリケーションの移行を開始する前に決定する必要の ある重要な事項の1つに、トランザクション制御を処理する 方法があります。Borland Database Engineアプリケーシ ョンでBorland Database Engineにトランザクション制御 を自動的に処理させる場合、唯一行う必要があるのは、デ ータへの変更を保存するすべての場所にApplyUpdatesへ の呼び出しを追加することです。dbExpressは、Boralnd Databas Engineとまったく同じように、トランザクション 制御を自動的に処理します。更新の適用後、ユーザーが同 じレコードセットで作業を続ける場合は、ClientDataSet のRefreshメソッドを呼び出すべきです。これによりソース クエリが再実行され、ClientDataSetに新しい結果セットが ロードされます。ユーザーは、ほかのユーザーによって加 えられたすべての変更を見ることができます。

Borland Database Engine ア プ リ ケ ー シ ョ ン で StartTransaction、Commit、およびRollbackへの呼び出し

を明示的に行っている場合、選択はより複雑になります。1

つの選択肢は、トランザクションに関連するすべてのコー ド を 削 除 し 、Commit へ の 各 呼 び 出 し を 適 切 な ClientDataSetのApplyUpdatesメソッドへの呼び出しに置

(13)

1. ユーザーがClientDataset内のデータを編集します。 き換えることです。これにより、dbExpressにトランザク ション制御を任せることができるので、コードが簡素化さ れ ま す 。 こ の 方 法 が 唯 一 機 能 し な い の は 、2つ以上の ClientDataSetの更新を単一トランザクション内で、一体で 処理する必要がある場合です。明示的なRollbackへの呼び 出しは、ClientDataSetのCancelUpdatesメソッドへの呼び 出しに置き換えます。CancelUpdatesは、ClientDataset の変更ログに含まれるペンディング中の変更を取り消しま す。もう1つの選択肢は、明示的なトランザクション制御ス テートメントを保持することです。意外にも、これは次の3 つの理由のために最も困難な方法です。 2. トランザクションを開始します。 3. ApplyUpdatesを呼び出します。 4. トランザクションをコミットまたはロールバックし ます。 プ ロ グ ラ ム の ト ラ ン ザ ク シ ョ ン 制 御 プ ロ セ ス を dbExpressモデルに移行するには、StartTransactionへの 各呼び出しを移動し、それを対応するCommitへの呼び出し の直前に置く必要があります。次に、StartTransactionへ の呼び出しとCommitへの呼び出しの間に、ApplyUpdates への呼び出しを追加します。 ・ 各コミットの前にApplyUpdatesへの呼び出しを追加する必 要があります。

Borland Database Engine Databaseコンポーネントお よびdbExpress SQLConnectionコンポーネントはともに、 StartTransactionメソッド、Commitメソッド、および Rollbackメソッドを持ちます。Borland Database Engine とは異なり、dbExpressでは、データベースでサポートし ている場合、複数のトランザクションを同時にアクティブ にできます。複数のトランザクションをサポートするには、 SQLConnectionのStartTransactionメソッド、Commitメ ソッド、およびRollbackメソッドがTTransactionDesc型の パラメータをとります。TTransactionDescは次のように宣 言されています。 ・ dbExpressのプロバイド/リゾルブアーキテクチャによる短 期間のトランザクションを利用する場合には、すべての StartTransactionへの呼び出しを移動する必要があります。 ・ StartTransaction、Commit、およびRollbackへのすべての呼 び出しを変更し、TTransactionDescパラメータを渡す必要が あります。 このように、明示的なトランザクションコードを削除す る方が、それを維持するよりも容易な作業です。それでは、 上記の3つの手順について、詳細を見ることにしましょう。 トランザクションを開始した後、Commitへの各呼び出しの 前に、トランザクションに関与する各ClientDataSetの ApplyUpdatesメソッドを呼び出す必要があります。これに より、ClientDataSetの変更ログ内の変更がデータベースに 適用されます。ApplyUpdatesを呼び出すまで、データベー スは変更されず、したがって何もコミットされません。

TTransactionDesc = packed record TransactionID : LongWord; GlobalID : LongWord; IsolationLevel : TTransIsolationLevel; CustomIsolation : LongWord; end; 各同時トランザクションについて、TTransactionDesc型 の変数を宣言し、同時にアクティブになるすべてのトラン ザクションで固有の番号をTransactionIdに設定する必要 があります。GlobalIdフィールドが使用されるのは、Oracle データベースのトランザクションを扱う場合に限られます。 IsolationLevel に は 、 xilDIRTYREAD 、 xilREADCOMMITTED、またはxilREPEATABLEREAD を設定する必要があります。CustomIsolationフィールドは 現在使用されていません。 Borland Database Engineのクライアント/サーバーア

プリケーションでは、トランザクション制御プロセスは次 のように行われます。 1. トランザクションを開始します。 2. ユーザーがデータを編集します。 3. トランザクションをコミットまたはロールバックし ます。

Borland Database Engineでは同時にアクティブになる 複数のトランザクションがサポートされないので、必要な 作業は、トランザクション制御ステートメントを含む各ユ ニットについて、そのuses句にあるユニットのインターフ ェースセクション内にTTransactionDesc型の単一の変数 を宣言することだけです。アプリケーションのスタートア ップコードで、TransactionIdフィールドに1を設定し、 IsolationLevelフィールドにxilREADCOMMITTEDまた このモデルでは、ユーザーがデータを編集している間、 常にトランザクションはアクティブです。dbExpressプロ バイド/リゾルブアーキテクチャの主な利点の1つは、短い トランザクション期間です。この利点を活かすには、ユー ザーが変更操作を行っている間、トランザクションがアク ティブにならないように、次の手順に従ってトランザクシ ョン制御プロセスを実行する必要があります。

(14)

はxilREPEATABLEREAD を 設 定 し ま す 。 最 後 に 、 StartTransaction、Commit、およびRollbackへのすべての 呼び出しを変更し、パラメータとしてTTransactionDesc変 数を渡す必要があります。 すべてのデータセットコンポーネントの置換 すべてのデータセットコンポーネントを置換することは、 変換プロセスにおいて最も大きな作業です。各Borland Database Engine QueryコンポーネントをSQLQueryコン ポ ー ネ ン ト に 置 換 し 、 各Borland Database Engine StoredProcコンポーネントをSQLStoredProcコンポーネ ントに置換する必要があります。このプロセスは、Borland Database Engineコンポーネントが、対応するdbExpress コンポーネントにないプロパティとイベントを持つことか ら、複雑な作業になります。存在しないプロパティへのコ ード内の参照をすべて削除する必要があります。 双方向のアクセスまたはレコードの編集を必要とする各 SQLQueryコンポーネントおよびSQLStoredProcコンポー ネントには、DataSetProviderとClientDataSetを追加する 必要があります。SQLQueryおよびSQLStoredProcにない イベントのイベントハンドラをClientDataSetの対応する イベントに接続します。既存コードへの変更を最小限に抑 えるために、置換対象のBorland Database Engine Query コ ン ポ ー ネ ン ト ま た はBorland Database Engine StoredProcコンポーネントと同じ名前をClientDataSetコ ン ポ ー ネ ン ト に 付 け る こ と を 考 慮 し て く だ さ い 。 SQLQueryコンポーネントおよびSQLStoredProcコンポー ネントに戻り、Fields Editorを使ってフィールドオブジェ クトのインスタンスを作成します。フィールドオブジェク トのインスタンスを作成した後、プライマリキー内の各フ ィールドでpfInKeyプロバイダフラグにtrueを設定します。 更新すべきでない計算フィールドがある場合は、そのフィ ールドのプロバイダフラグpfInUpdateおよびpfInWhere にfalseを設定します。 DataSetProviderおよびClientDataSetを追加する必要 のない場合もあります。たとえば、あるクエリの結果セッ トをその先頭行から末尾行まで一度に読み取り、そのいず れかのフィールド値をコンボボックスまたはリストボック スのItemsプロパティに追加する場合を考えてください。こ の例では、1方向にのみレコードをスキャンするので、必要 になるのは読み取り専用アクセスだけです。したがって、 SQLQueryコンポーネントまたはSQLStoredProcコンポー ネントを直接使用できます。

Borland Database Engineアプリケーションでキャッシ

ュ更新機能を使用している場合は、Borland Database Engine QueryコンポーネントをSQLQueryコンポーネン トに変換するときにUpdateSQLコンポーネントを削除し ます。ClientDataSetおよびDataSetProviderが同じ機能と 利点を提供しているので、dbExpressではキャッシュ更新 機能は必要ありません。 最後に、前節のトランザクション制御についての議論で 説明したように、ClientDataSetのApplyUpdatesメソッド への呼び出しを追加し、これによってClientDataSetのロー カルバッファ内でのデータ変更をデータベースに書き込み ます。 データ型のマッピング

dbExpressは、Borland Database Engineでは扱わなか った2つの新しいデータ型を使用しています。倍精度浮動小 数点値に収まらないすべての数値は、TFMTBCDFieldオブ ジ ェ ク ト に よ っ て ア プ リ ケ ー シ ョ ン に 返 さ れ ま す 。 TFMTBCDFieldオブジェクト内の値は、最大精度32桁の True BCD 値 で あ る TBCD 型 と し て 格 納 さ れ ま す 。 TFMTBCDField内の値に対して数値演算を実行するには、 その値をVariant変数に格納するためにAsVariantプロパ ティを使用します。 dbExpressは、TSQLTimeStampFieldフィールドオブジ ェ ク ト 型 を 使 っ て date-time 値 を 返 し ま す 。 TSQLTimeStampFieldでは、TSQLTimeStamp型の変数に date-time情報が格納されます。TSQLTimeStampは、年、 月、日、時、分、秒、および端数のための個別フィールド を持つDelphiレコードです。端数は、ミリ秒単位の数値で す。TSQLTimeStampには、date-time値をその精度を損失 し な い で 格 納 で き ま す 。TSQLTimeStampField は 、 date-time値をその他のデータ型に変換するためのAs…プ ロパティを持ちます。 BatchMove コンポーネントの置換

Borland Database Engine BatchMoveコンポーネント に相当するdbExpressのコンポーネントは存在しません。 アプリケーション内でBatchMoveコンポーネントを使用し ている場合は、それをコードに置換する必要があります。

デスクトップデータベースアプリケーションのdbExpressへの移行

ParadoxやdBaseのようなデスクトップデータベースを 使用するアプリケーションをdbExpressに移行する場合、 その他にも対処すべき問題があります。 データ変換 dbExpressではParadoxテーブルおよびdBaseテーブル がサポートされないので、dbExpressでサポートされる SQLデータベースサーバーに変換してから、新しいデータ ベースにデータを移動する必要があります。このための方

参照

関連したドキュメント

に関して言 えば, は つのリー群の組 によって等質空間として表すこと はできないが, つのリー群の組 を用いればクリフォード・クラ イン形

(※)Microsoft Edge については、2020 年 1 月 15 日以降に Microsoft 社が提供しているメジャーバージョンが 79 以降の Microsoft Edge を対象としています。2020 年 1

つの表が報告されているが︑その表題を示すと次のとおりである︒ 森秀雄 ︵北海道大学 ・当時︶によって発表されている ︒そこでは ︑五

平成 28 年度については、介助の必要な入居者 3 名が亡くなりました。三人について

このアプリケーションノートは、降圧スイッチングレギュレータ IC 回路に必要なインダクタの選択と値の計算について説明し

析の視角について付言しておくことが必要であろう︒各国の状況に対する比較法的視点からの分析は︑直ちに国際法

次に、14 ページの下の表を御覧ください。表 5.2-1 に計画建築物の概要を示してござい ます。区域面積は約 2.4ha、延床面積は約 42 万 m 2

大村 その場合に、なぜ成り立たなくなったのか ということ、つまりあの図式でいうと基本的には S1 という 場