Caché ADO.NET Managed Provider クラスの使用法
Caché ADO.NET Managed Provider を使用すれば、Connection、Command、CommandBuilder、DataReader、DataAdapter などの汎用 ADO.NET Managed Provider クラスの完全互換バージョンで、.NET プロジェクトから Caché データベースにアクセスできます。以下のクラスは、標準 ADO.NET Managed Provider クラスの Caché 固有の実装です。
-
CacheConnection — 指定した Caché ネームスペースのアプリケーションとデータベース間の接続を表します。CacheConnection の使用法の詳細は、“Caché データベースへの接続” を参照してください。
-
CacheCommand — CacheConnection で指定したネームスペースでデータベースに対して実行する SQL 文またはストアド・プロシージャをカプセル化します。
-
CacheCommandBuilder — 単一テーブルのクエリをカプセル化したオブジェクトによって行われた変更に合わせて Caché データベースを調整する SQL コマンドを自動で生成します。
-
CacheDataReader — CacheCommand で指定した結果セットを取得する方法を提供します。CacheDataReader オブジェクトは、結果セットに対する前方向のみの迅速なアクセスを提供します。ただし、ランダム・アクセスには対応していません。
-
CacheDataAdapter — CacheConnection で指定したネームスペースでデータにマッピングされる結果セットをカプセル化します。これは、ADO.NET DataSet への入力や Caché データベースの更新に使用され、結果セットへの効率的なランダム・アクセス接続を実現します。
この章では、Caché ADO.NET Managed Provider クラスを使用したコードの具体例を示します。ここで説明する内容は以下のとおりです。
-
ADO.NET Managed Provider クラスの概要 — Caché ADO.NET Managed Provider クラスの使用法について簡単に説明します。
-
CacheCommand と CacheDataReader の使用法 — 読み取り専用の簡単なクエリの実行方法について説明します。
-
CacheParameter を使用した SQL クエリの使用法 — クエリにパラメータを渡す方法について説明します。
-
CacheDataAdapter と CacheCommandBuilder の使用法 — データの変更と更新を行います。
-
トランザクションの使用法 — トランザクションをコミットまたはロールバックする方法について説明します。
この章の例では SQL 文のみを使用して Caché データにアクセスしていますが、“.NET 用 Caché オブジェクト・バインディングの使用法” で説明しているように、データベースのインスタンスをリレーショナル・データベースの行ではなくオブジェクトと見なしてアクセスすることもできます。どちらのアクセス方法も同じプログラム内で使用できます。
この章に示す例は、bookdemos プロジェクト (詳細は、“Caché .NET サンプル・プログラム” を参照) で提供されているサンプルからの抜粋です。これらの例では、標準のコーディング作業に精通しているユーザを対象としているため、エラー・トラップ (try/catch) 文など、内容に直接関係のないコードは省略されています。完成された実用的なコード例の詳細は、<Cache-install-dir>\dev\dotnet\samples\bookdemos にあるメイン・コード・ファイル SampleCode.cs を参照してください (ご使用のシステムの <Cache-install-dir> の場所については、"Caché インストール・ガイド" の “Caché の既定のインストール・ディレクトリ” を参照してください)。
ADO.NET Managed Provider クラスの概要
ADO.NET Managed Provider クラスの Caché 実装を使用するプロジェクトは非常にシンプルです。Sample.Person データベースを開いてその項目を読み取る、完成された実用的なコンソール・プログラムを以下に示します。
using System;
using InterSystems.Data.CacheClient;
using InterSystems.Data.CacheTypes;
namespace TinySpace {
class TinyProvider {
[STAThread]
static void Main(string[] args) {
CacheConnection CacheConnect = new CacheConnection();
CacheConnect.ConnectionString = "Server = localhost; "
+ "Port = 1972; " + "Namespace = SAMPLES; "
+ "Password = SYS; " + "User ID = _SYSTEM;";
CacheConnect.Open();
string SQLtext = "SELECT * FROM Sample.Person WHERE ID = 1";
CacheCommand Command = new CacheCommand(SQLtext, CacheConnect);
CacheDataReader Reader = Command.ExecuteReader();
while (Reader.Read()) {
Console.WriteLine("TinyProvider output: \r\n "
+ Reader[Reader.GetOrdinal("ID")] + ": "
+ Reader[Reader.GetOrdinal("Name")]);
};
Reader.Close();
Command.Dispose();
CacheConnect.Close();
} // end Main()
} // end class TinyProvider
}
このプロジェクトには、以下の重要な機能があります。
-
using 文を使用すると、CacheClient アセンブリにアクセスできます。
using InterSystems.Data.CacheClient; using InterSystems.Data.CacheTypes;
-
CacheConnection オブジェクトは、Caché の SAMPLES ネームスペースへの接続を作成する場合、および開く場合に使用します。
CacheConnection CacheConnect = new CacheConnection(); CacheConnect.ConnectionString = "Server = localhost; " + "Port = 1972; " + "Namespace = SAMPLES; " + "Password = SYS; " + "User ID = _SYSTEM;"; CacheConnect.Open();
-
CacheCommand オブジェクトは、CacheConnection オブジェクトと SQL 文を使用して、ID が 1 の Sample.Person のインスタンスを開きます。
string SQLtext = "SELECT * FROM Sample.Person WHERE ID = 1"; CacheCommand Command = new CacheCommand(SQLtext, CacheConnect);
-
CacheDataReader オブジェクトは、以下のように行のデータ項目へのアクセスに使用します。
CacheDataReader Reader = Command.ExecuteReader(); while (Reader.Read()) { Console.WriteLine("TinyProvider output: \r\n " + Reader[Reader.GetOrdinal("ID")] + ": " + Reader[Reader.GetOrdinal("Name")]); };
CacheCommand と CacheDataReader の使用法
読み取り専用の単純なクエリであれば、CacheCommand および CacheDataReader を使用するだけで実行できます。すべてのデータベース・トランザクションと同様、このようなクエリの場合でも CacheConnection オブジェクトを開いておく必要があります。
この例では、既存の接続を使用する新しい CacheCommand オブジェクトに SQL クエリ文字列が渡されます。
string SQLtext = "SELECT * FROM Sample.Person WHERE ID < 10";
CacheCommand Command = new CacheCommand(SQLtext, CacheConnect);
クエリの結果は、CacheDataReader オブジェクトに返されます。SQL 文で指定した列名を参照することで、プロパティにアクセスできます。
CacheDataReader reader = Command.ExecuteReader();
while (reader.Read()) {
Display.WriteLine(
reader[reader.GetOrdinal("ID")] + "\t"
+ reader[reader.GetOrdinal("Name")] + "\r\n\t"
+ reader[reader.GetOrdinal("Home_City")] + " "
+ reader[reader.GetOrdinal("Home_State")] + "\r\n");
};
列名ではなく列番号を使用した場合も、同じレポートを生成できます。CacheDataReader オブジェクトでは、前方への読み取りのみが可能です。データ・ストリームの先頭に戻るには、この読み取り操作をいったん終了し、クエリを再実行して読み取り操作をもう一度開始する必要があります。
reader.Close();
reader = Command.ExecuteReader();
while (reader.Read()) {
Display.WriteLine(
reader[0] + "\t"
+ reader[4] + "\r\n\t"
+ reader[7] + " "
+ reader[8] + "\n");
}
実用的な例は、bookdemos サンプル・プログラムの ADO_1_CommandReader() メソッドを参照してください (“Caché .NET サンプル・プログラム” を参照)。
CacheParameter を使用した SQL クエリの使用法
CacheParameter オブジェクトは、より複雑な SQL クエリに必要です。以下の例では、CacheParameter で指定した文字列から始まる値を Name に持つすべての行からデータを選択しています。
string SQLtext =
"SELECT ID, Name, DOB, SSN "
+ "FROM Sample.Person "
+ "WHERE Name %STARTSWITH ?"
+ "ORDER BY Name";
CacheCommand Command = new CacheCommand(SQLtext, CacheConnect);
このパラメータ値は、Name の先頭の文字列が A である行をすべて取得するように設定されています。このパラメータは CacheCommand オブジェクトに渡されます。
CacheParameter Name_param =
new CacheParameter("Name_col", CacheDbType.NVarChar);
Name_param.Value = "A";
Command.Parameters.Add(Name_param);
既定では、SQL 文はサーバ上で実行される前に検証されません。これは、クエリごとにサーバを 2 回呼び出す必要があるためです。検証が必要な場合は、CacheCommand.Prepare() を呼び出して、Caché サーバに対する SQL 文の構文を検証します。
CacheDataReader オブジェクトでは、前述の例と同様に結果のデータ・ストリームにアクセスできます。
CacheDataReader reader = Command.ExecuteReader();
while (reader.Read()) {
Display.WriteLine(
reader[reader.GetOrdinal("ID")] + "\t"
+ reader[reader.GetOrdinal("Name")] + "\r\n\t"
+ reader[reader.GetOrdinal("DOB")] + " "
+ reader[reader.GetOrdinal("SSN")] + "\r\n");
};
実用的な例は、bookdemos サンプル・プログラムの ADO_2_Parameter() メソッドを参照してください (“Caché .NET サンプル・プログラム” を参照)。
プロキシ・オブジェクトからの Caché クエリ・メソッドの実行には、CacheCommand クラス、CacheParameter クラス、および CacheDataReader クラスも使用されます。詳細は、“Caché クエリの使用法” を参照してください。
CacheDataAdapter と CacheCommandBuilder の使用法
連続的な読み取り専用アクセス以外のアクセスをアプリケーションで行う必要がある場合は、CacheCommand および CacheDataReader クラスでは不十分です。このような場合は、CacheDataAdapter および CacheCommandBuilder クラスによって完全なランダム読み取り/書き込みアクセスを提供できます。次の例では、これらのクラスを使用して、一連の Sample.Person 行を取得し、1 つの行を読み取って変更し、行を削除して新しい行を追加し、変更内容を Caché データベースに保存します。
CacheDataAdapter コンストラクタは、CacheCommand と同様に、SQL コマンドと CacheConnection オブジェクトをパラメータとして受け取ります。この例では、Name が A または B で始まるすべての Sample.Person 行のデータが結果セットに含まれます。Adapter オブジェクトは、この結果セットを Person という名前のテーブルにマッピングします。
string SQLtext =
" SELECT ID, Name, SSN "
+ " FROM Sample.Person "
+ " WHERE Name < 'C' "
+ " ORDER BY Name ";
CacheDataAdapter Adapter = new CacheDataAdapter(SQLtext, CacheConnect);
Adapter.TableMappings.Add("Table", "Person");
Adapter オブジェクトに対して CacheCommandBuilder オブジェクトを作成します。Adapter オブジェクトによってマッピングされたデータが変更されると、Adapter は Builder によって生成された SQL 文を使用して、Caché データベース内の対応する項目を更新します。
CacheCommandBuilder Builder = new CacheCommandBuilder(Adapter);
ADO の DataSet オブジェクトを作成し、Adapter を使ってデータを格納します。このオブジェクトには、PersonTable オブジェクトを定義するために使用されるテーブルが 1 つだけ含まれています。
System.Data.DataSet DataSet = new System.Data.DataSet();
Adapter.Fill(DataSet);
System.Data.DataTable PersonTable = DataSet.Tables["Person"];
簡単な foreach コマンドを使用して、PersonTable 内の各行を読み取ることができます。この例では、1 行目の Name を保存し、それを "Fudd, Elmer" に変更します。データを出力すると、すべての名前がアルファベット順に並んでいますが、1 行目だけは F で始まります。データを出力した後で、1 行目の Name を元の値にリセットします。どちらの変更も、DataSet 内のデータに対してのみ行われています。Caché データベース内の元のデータはまだ変更されていません。
if (PersonTable.Rows.Count > 0) {
System.Data.DataRow FirstPerson = PersonTable.Rows[0];
string OldName = FirstPerson["Name"].ToString();
FirstPerson["Name"] = "Fudd, Elmer";
foreach (System.Data.DataRow PersonRow in PersonTable.Rows) {
Display.WriteLine("\t"
+ PersonRow["ID"] + ":\t"
+ PersonRow["Name"] + "\t"
+ PersonRow["SSN"]);
}
FirstPerson["Name"] = OldName;
}
次のコードでは、1 行目を削除するようマーク付けし、次に新しい行を作成して追加します。ここでも、これらの変更は DataSet オブジェクトに対してのみ行われています。
FirstPerson.Delete();
System.Data.DataRow NewPerson = PersonTable.NewRow();
NewPerson["Name"] = "Budd, Billy";
NewPerson["SSN"] = "555-65-4321";
PersonTable.Rows.Add(NewPerson);
最後に、Update() メソッドを呼び出します。Adapter は、今度は CacheCommandBuilder のコードを使用して、DataSet オブジェクトの Person テーブルに含まれる現在のデータで Caché データベースを更新します。
Adapter.Update(DataSet, "Person");
実用的な例は、bookdemos サンプル・プログラムの ADO_3_AdapterBuilder() メソッドを参照してください ("Caché .NET サンプル・プログラム" を参照)。
トランザクションの使用法
Transaction クラスは、SQL トランザクションの指定に使用します (Caché でのトランザクションの使用法に関する概要は、"Caché SQL の使用法" の “トランザクション処理” を参照してください)。以下の例では、SSN が一意でない場合、トランザクション Trans が失敗して、ロールバックされます。
CacheTransaction Trans =
CacheConnect.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
try {
string SQLtext = "INSERT into Sample.Person(Name, SSN) Values(?,?)";
CacheCommand Command = new CacheCommand(SQLtext, CacheConnect, Trans);
CacheParameter Name_param =
new CacheParameter("name", CacheDbType.NVarChar);
Name_param.Value = "Rowe, Richard";
Command.Parameters.Add(Name_param);
CacheParameter SSN_param =
new CacheParameter("ssn", CacheDbType.NVarChar);
SSN_param.Value = "234-56-3454";
Command.Parameters.Add(SSN_param);
int rows = Command.ExecuteNonQuery();
Trans.Commit();
Display.WriteLine("Added record for " + SSN_param.Value.ToString());
}
catch (Exception eInsert) {
Trans.Rollback();
WriteErrorMessage("TransFail", eInsert);
}
実用的な例は、bookdemos サンプル・プログラムの ADO_4_Transaction() メソッドを参照してください (“Caché .NET サンプル・プログラム” を参照)。