ヘッダーをスキップ
Oracle Database 2日で.NET開発者ガイド
11gリリース2(11.2)
B56266-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

4 Oracle Data Provider for .NETでの取得と更新

この章の内容は次のとおりです。

コマンド・オブジェクトの使用

データベース内のデータを表示、編集、挿入または削除するには、SQLコマンド、ストアド・プロシージャまたは表名を指定して、OracleCommandオブジェクトにリクエストをカプセル化する必要があります。OracleCommandオブジェクトは、リクエストを作成してデータベースに送信し、結果を戻します。

コマンド・オブジェクトを使用するには、次の手順を実行します。

  1. 第3章「ODP.NETによる単純な.NETアプリケーションの作成」で作成したアプリケーションHR_Connect_xxから、Form1.xxのコピーを2つ作成します。 コピーを作成する方法については、付録B「フォームのコピー」を参照してください。

    コピーにForm2.csまたはForm2.vb、およびForm3.csまたはForm3.vbと名前を付けます。最初のコピーは、この章の前半で使用します。2つ目のコピーは、この章の後半で使用します。

  2. Form2.csまたはForm2.vbを開きます。

    コード・ファイルの名前は変更しましたが、プロジェクト内の実際のフォーム・コントロールの名前は変更していないため、デザイナのフォームはまだForm1となっていることに注意してください。

  3. SQL問合せを表す文字列を作成し、try文の本体に追加します。

    新しいコードは太字で示しています。

    Visual C#:

    try
    {
        conn.Open();
        connect.Enabled = false;
    
        // SQL Statement
        string sql = "select department_name from departments"
           + " where department_id = 10";
    }
    

    Visual Basic:

    Try
          conn.Open()
          connect.Enabled = False
    
         Dim sql As String = "select department_name from departments" & _
           "where department_id = 10"
    
    
  4. 新しいsql変数を使用してOracleCommandオブジェクトを作成し、テキスト・コマンドが実行されるようにCommandTypeプロパティを設定します。

    Visual C#:

    try
    {
        conn.Open();
        connect.Enabled = false;
    
        // SQL Statement
        string sql = "select department_name from departments"
           + " where department_id = 10";
    
    OracleCommand cmd = new OracleCommand(sql, conn);
    cmd.CommandType = CommandType.Text;
    }
    

    Visual Basic:

    Try
          conn.Open()
          connect.Enabled = False
    
          Dim sql As String = "select department_name from departments" & _
             "where department_id = 10"
    
    Dim cmd As New OracleCommand(sql, conn)
    cmd.CommandType = CommandType.Text
    
  5. 実行した内容を保存します。

データの取得: 単純な問合せ

この項では、データベースからデータを取得する方法を説明します。

OracleCommandオブジェクトのExecuteReader()メソッドによりOracleDataReaderオブジェクトが戻されます。これにアクセスすることでフォームに結果を表示できます。このアプリケーションでは、ListBoxを使用して結果を表示します。

データを取得するには、次の手順を実行します。

  1. 次に示すコードをconnect_Click()メソッドのTryブロックの最後に追加して、OracleDataReaderオブジェクトを作成します。

    これにより、問合せ結果を読み取ることができます。

    Visual C#:

    OracleDataReader dr = cmd.ExecuteReader();
    dr.Read();
    

    Visual Basic:

    Dim dr As OracleDataReader = cmd.ExecuteReader()
    dr.Read()
    
  2. 設計ビューでForm1を開きます。「View」メニューから「Designer」を選択します。

  3. 「View」メニューから「Toolbox」を選択します。

  4. 「Toolbox」から「Label」を選択し、Form1にドラッグします。

  5. 「View」メニューから「Properties Window」を選択します。

  6. 「Properties」ウィンドウで、ラベルの「Text」Departmentに変更します。

  7. 「Toolbox」の「Window」フォームから、「ListBox」を選択し、Form1にドラッグします。

  8. 「Properties」ウィンドウの「Design」で、「Name」departmentsに変更します。

    simple1.gifの説明が続きます。
    simple1.gifの説明

  9. 問合せ結果からデータを取得するためのアクセッサ型メソッドを追加します。

    「Connect」ボタンをダブルクリックしてconnect_click()メソッドを編集し、次に示すコードをTryブロックの最後に追加します。

    Visual C#:

    departments.Items.Add(dr.GetString(0));
    

    Visual Basic:

    departments.Items.Add(dr.GetString(0))
    

    GetStringなどの型指定されたアクセッサは、ネイティブの.NETデータ型およびネイティブのOracleデータ型を戻します。結果セットのどの列を戻すかは、アクセッサに渡されたゼロベースの序数で指定します。

  10. アプリケーションをビルドして保存します。

  11. アプリケーションを実行します。ログインおよびデータソースを入力します。

    接続すると、「Department」リスト・ボックスにAdministrationと表示されます。これはHRスキーマに含まれる部門番号10の正しい名前で、SELECT文でリクエストしたものです。

    simple2.gifの説明が続きます。
    simple2.gifの説明

データの取得: バインド変数

バインド変数はSQL文内のプレースホルダです。データベースではSQL文を受信すると、その文がすでに実行されたことがありメモリーに格納されているかどうかが確認されます。その文がメモリーに存在する場合、Oracle Databaseではその文を再利用でき、文の解析と最適化のタスクがスキップされます。バインド変数を使用すると、異なる入力値でも文の再利用が可能です。また、バインド変数を使用すると、データベースの問合せパフォーマンスが向上するだけでなく、入力に含まれるリテラル引用符の特別な処理が不要になり、SQLインジェクション攻撃から保護することができます。

次のコードは、バインド変数を使用せずに、文のWHERE句に値10を指定する標準的なSELECT文です。

SELECT department_name FROM departments WHERE department_id = 10

次のコードは、数値をバインド変数:department_idで置き換えたものです。バインド変数識別子は、常に1つのコロン(:)で始まります。

SELECT department_name FROM departments WHERE department_id = :department_id

バインド変数はUPDATEINSERTおよびDELETE文でも使用でき、ストアド・プロシージャでも使用できます。次のコードは、UPDATE文でバインド変数を使用する方法を示しています。

UPDATE departments SET department_name = :department_name
  WHERE departname_id = : department_id

詳細は、「データの挿入、削除および更新」を参照してください。

.NETコードで各バインド変数を表すには、OracleParameterクラスを使用できます。OracleParameterCollectionクラスには、各文のOracleCommandオブジェクトと関連付けられたOracleParameterオブジェクトが含まれています。OracleCommandクラスは、SQL文をデータベースに渡し、結果をアプリケーションに戻します。

変数は、OracleCommandプロパティBindByNameの設定(デフォルトはfalse)によって、位置または名前でバインドできます。

バインド・モード(位置指定または名前指定)の他に、.NET開発者はDirectionOracleDbTypeSizeおよびValueの各プロパティを、各パラメータ・オブジェクトに設定します。

バインド変数を使用してデータを取得するには、次の手順を実行します。

  1. Departmentsという名前のListBoxを右側に移動します。

  2. 「View」メニューから「Toolbox」を選択します。

  3. 「Toolbox」から「TextBox」を選択し、Form1のDepartmentという名前のラベルの下にドラッグします。

  4. 「View」メニューから「Properties Window」を選択します。

  5. 「Properties」ウィンドウで、「Name」departmentIDに変更します。

    bind0.gifの説明が続きます。
    bind0.gifの説明

  6. 次に示すコードをconnect_Click()メソッドのTryブロックに追加して、バインド変数が使用されるようにSELECT文を変更します。

    変更されたコードまたは新しいコードは太字で示しています。

    Visual C#:

    string sql = "select department_name from departments where department_id = " +
      ":department_id";
    OracleCommand cmd = new OracleCommand(sql, conn);
    cmd.CommandType = CommandType.Text;
    OracleParameter p_department_id = new OracleParameter();
    p_department_id.OracleDbType = OracleDbType.Decimal;
    p_department_id.Value = departmentID.Text;
    cmd.Parameters.Add(p_department_id); 
    
    OracleDataReader dr = cmd.ExecuteReader();
    dr.Read();
    
    departments.Items.Add(dr.GetString(0));
    

    Visual Basic:

    Dim sql As String = "select department_name from departments where" & _
      "department_id= ":department_id"
    Dim cmd As OracleCommand = New OracleCommand(sql, conn)
    cmd.CommandType = CommandType.Text
    Dim p_department_id as OracleParameter = new OracleParameter()
    p_department_id.OracleDbType = OracleDbType.Decimal
    p_department_id.Value = departmentID.Text
    cmd.Parameters.Add(p_department_id) 
    
    Dim dr As OracleDataReader = cmd.ExecuteReader()
    dr.Read()
    
    departments.Items.Add(dr.GetString(0))
    

    このコードでは、パラメータ・オブジェクトはOracleDbTypeプロパティを設定しますが、Directionプロパティにはデフォルト値Inputを使用するため、設定は不要です。オブジェクトは入力パラメータであり、データ・プロバイダは値からサイズを判断できるため、Sizeプロパティを設定する必要はありません。

  7. アプリケーションを保存して実行します。

  8. ログイン情報と、HRスキーマの代表的な部門番号(50など)を入力します。

  9. 「Connect」をクリックします。

    部門IDに対応する部門名がアプリケーションから戻されます。

    bind1.gifの説明が続きます。
    bind1.gifの説明

データの取得: 複数の値

データベースから複数の値を取得することが必要になる場合はよくあります。複数の列および複数の行の値を取得するには、DataReaderオブジェクトを使用できます。次の例で、複数の列や複数の行に対する問合せについて考えてみます。

SELECT department_id, department_name, manager_id, location_id
  FROM departments
  WHERE department_id < 100

DataReaderオブジェクトから複数の行を処理するには、ループ構造が必要です。また、複数の行を表示できるコントロールが役立ちます。OracleDataReaderオブジェクトは前進専用で読取り専用のカーソルであるため、Windows FormsのDataGridコントロールなどの、更新可能なコントロールまたは後方にスクロールできるコントロールにはバインドできません。ただし、OracleDataReaderオブジェクトはListBoxコントロールと互換性があります。

複数の値を取得するには、次の手順を実行します。

  1. connect_Click()メソッドのTryブロックで、複数の行の結果セットが戻され、部門名を表示するreadメソッドを囲むwhileループを追加するようにSQL問合せを変更します。

    Visual C#:

    try
    {
      ...
    string sql = "select department_name from departments where department_id" +
      "< :department_id";
    ...
      while (dr.Read())
      {
        departments.Items.Add(dr.GetString(0));
      }
    }
    

    Visual Basic:

    Try
      ...
      Dim sql As String = "select department_name from departments " & _
            "where department_id < :department_id"
    ...
      While (dr.Read())
        departments.Items.Add(dr.GetString(0))
      End While
    
  2. アプリケーションを保存して実行します。

  3. ログイン情報を入力し、部門に50と入力します。

  4. 「Connect」をクリックします。

    問合せに対応する部門名が、アプリケーションから戻されます。

    bind2.gifの説明が続きます。
    bind2.gifの説明

Oracle Data Provider for .NETでのDataSetクラスの使用

DataSetクラスでは、メモリーに常駐するデータベース・データのコピーが提供されます。これは、リレーショナル・データまたはXMLデータを格納する1つ以上の表で構成されます。OracleDataReaderオブジェクトとは異なり、DataSetは更新可能で後方にスクロールできます。

Datasetクラスを使用するには、次の手順を実行します。

  1. 第3章で作成したForm1のコピーを作成していない場合はForm1をコピーし、付録B「フォームのコピー」で説明するとおり、Form3.vbまたは.csという名前を付けます。Form1.xxがSolution Explorerに表示されない場合は、「Project」メニューから「Show All Files」を選択します。

  2. 「View」メニューから「Designer」ビューを選択します。

  3. 「View」メニューから「Toolbox」を選択します。

  4. 「Toolbox」から「DataGridView」を選択し、Form1にドラッグします。

  5. 「View」メニューから「Properties Window」を選択します。

  6. 「Properties」ウィンドウで、データ・グリッド・ビューの「Name」departmentsに変更します。

    dataset1.gifの説明が続きます。
    dataset1.gifの説明

  7. 「View」メニューから「Code」を選択します。

  8. 次に示すように、コードのconn宣言の直後に、クラス変数への変数宣言を追加します。

    Visual C#:

    public partial class Form1 : Form
    {
      public Form1()
      {
          InitializeComponent();
      }
      private OracleConnection conn = new OracleConnection();
      private OracleCommand cmd;
      private OracleDataAdapter da;
      private OracleCommandBuilder cb;
      private DataSet ds;
    ...
    

    Visual Basic:

    Public Class Form1    Dim conn As New OracleConnection     Private cmd As OracleCommand
        Private da As OracleDataAdapter
        Private cb As OracleCommandBuilder
        Private ds As DataSet
    
  9. connect_Click()メソッドのTryブロックに、次のコードを追加します。

    • データベースを問い合せるコード

    • コマンドの問合せ結果をDataSetに埋め込むコード

    • DataSetをデータ・グリッド(departments)にバインドするコード

    Visual C#:

    conn.Open();
    connect.Enabled = false;
    
    string sql = "select * from departments where department_id < 60";
    cmd = new OracleCommand(sql, conn);
    cmd.CommandType = CommandType.Text;
    
    da = new OracleDataAdapter(cmd);
    cb = new OracleCommandBuilder(da);
    ds = new DataSet();
    
    da.Fill(ds);
    
    departments.DataSource = ds.Tables[0];
    

    Visual Basic:

    conn.Open()
    connect.Enabled = False
    
    Dim sql As String = "select * from departments where department_id < 60"
    cmd = New OracleCommand(sql, conn)
    cmd.CommandType = CommandType.Text
    
    da = New OracleDataAdapter(cmd)
    cb = New OracleCommandBuilder(da)
    ds = New DataSet()
    
    da.Fill(ds)
    
    departments.DataSource = ds.Tables(0)
    
  10. アプリケーションをビルドして保存します。

  11. アプリケーションを実行し、ログインおよびデータソースを入力します。

    データベースに正しく接続されると、データ・グリッドに問合せ結果が移入されます。

    dataset3.gifの説明が続きます。
    dataset3.gifの説明

データベースの更新の有効化

この時点で、DataSetにはデータベース・データのクライアント・コピーが保持されています。この項では、クライアント・データの変更をデータベースに保存できるようにするボタンを追加します。その後の項では、データの更新、挿入および削除のテスト方法を説明します。

DataSetからデータベースにデータを保存できるようにするには、次の手順を実行します。

  1. 「Toolbox」から「Button」をForm1にドラッグ・アンド・ドロップします。

  2. 「Properties」ウィンドウで、ボタンの「Name」saveに変更します。

    TextプロパティをSaveに変更します。

  3. 「Properties」ウィンドウの上部で、「Events」(稲妻のアイコン)をクリックします。イベントのリストでクリック・イベントを選択します。2番目の列にイベント名save_Clickを入力します。

    dataset2.gifの説明が続きます。
    dataset2.gifの説明

  4. 「View」メニューから「Code」を選択します。

  5. 次に示すように、データを更新するコードをsave_Click()メソッドの本体に追加します。

    Visual C#:

    da.Update(ds.Tables[0]);
    

    Visual Basic:

    da.Update(ds.Tables(0))
    

    「Error List」にエラーが表示される場合があります。これらのエラーは、次の手順でコードを追加する表示されなくなります。

  6. Form()メソッドまたはForm1_Loadメソッドに、次のコードを追加します。

    Visual C#:

    public Form1()
    {
        InitializeComponent();
        save.Enabled = false;
    }
    

    Visual Basic:

    Private Sub Form1_Load(ByVal sender As System.Object, & _
        ByVal e As System.EventArgs) Handles MyBase.Load
        save.Enabled = false
    
    
  7. 次のように、connect_Click()メソッドのTryブロックに、「Save」ボタンを有効にするコードを追加します。

    Visual C#:

    conn.Open();
     ...
    departments.DataSource = ds.Tables[0];
    
    save.Enabled = true;
    

    Visual Basic:

    conn.Open()
    ...
    departments.DataSource = ds.Tables(0)
    
    save.Enabled = True
    
  8. conn.Dispose()コールをconnect_Click()メソッドのFinallyブロックから削除します。

    注意: この例で前に使用したコードでは、接続を破棄またはクローズするためにこのメソッドが必要でした。しかし、コードを変更したため、問合せ結果が戻された後も接続をオープン状態のままにし、エンド・ユーザーによるデータ変更がデータベースに伝播されるようにする必要があります。一般的なオーバーライド・コールであるcomponents.Dispose()は、すでにForm1の定義に含まれています。

  9. アプリケーションをビルドして保存します。

  10. アプリケーションを実行し、ログインおよびデータソースを入力します。

    データベースに正しく接続されると、データ・グリッドに問合せ結果が移入されます。

    dataset3a.gifの説明が続きます。
    dataset3a.gifの説明

データの挿入、削除および更新

この項では、新しいアプリケーションを使用してデータベースのデータを直接操作する方法を説明します。

データを挿入、削除および更新するには、次の手順を実行します。

  1. 前の項で作成したアプリケーションを実行し、ログインおよびデータソースを入力して、データベースに接続します。

  2. データ・グリッドの一番下にある*プロンプトで、新しいレコードを入力します。

    • DEPARTMENT_ID」に5と入力します。

    • DEPARTMENT_NAME」にCommunity Outreachと入力します。

    • MANAGER_ID」には値を入力せず、そのままにします。

    • LOCATION_ID」に1700と入力します。

    dataset4.gifの説明が続きます。
    dataset4.gifの説明

  3. 「Save」をクリックします。

  4. アプリケーションを閉じ、新しいレコードが保存されているかどうかを確認します。

  5. アプリケーションを再度実行し、データベースに接続します。

    DEPARTMENT_IDが番号順に表示され、新しい部門がDEPARTMENTS表の先頭にあることを確認します。

  6. 部門名をCommunity Volunteersに変更して、「Save」ボタンをクリックします。

    dataset10.gifの説明が続きます。
    dataset10.gifの説明

  7. 手順4を繰り返します。アプリケーションを再度実行し、データベースに接続して、部門名が変更されていることを確認します。

  8. 変更したばかりのレコード全体を選択し(一番左の列にあるカーソル・アイコンをクリック)、[Delete]キーを使用してこのレコードを削除します。「Save」ボタンをクリックします。 dataset11.gifの説明が続きます。
    dataset11.gifの説明

  9. 手順4を繰り返します。アプリケーションを再度実行し、データベースに接続して、新しいレコードがDEPARTMENTS表に含まれていないことを確認します。

  10. アプリケーションを閉じます。