Visual C++ で SqlDataAdapter オブジェクトを使用して、SQL Server データベースを更新する

この記事では、オブジェクトを使用して、SqlDataAdapterMicrosoft Visual C++のSQL Server データベースを更新する方法について説明します。

元の製品バージョン: Visual C++
元の KB 番号: 308510

概要

オブジェクトはSqlDataAdapter、ADO.NET オブジェクトとSQL Server DataSet データベースの間のブリッジとして機能します。 これは、次の操作を行うために使用できる中間オブジェクトです。

  • SQL Server DataSet データベースから取得したデータを ADO.NET に設定します。
  • を使用してデータに加えられた変更 (挿入、更新、削除) を反映するようにデータベースを更新しますDataSet。この記事では、Visual C++ .NET コード サンプルを提供し、オブジェクトを使用して、データベース内のテーブルのデータが格納されたオブジェクトに対してDataSet実行されるデータ変更を使用して、SQL Server データベースを更新する方法SqlDataAdapterを示します。

この記事では、.NET Framework クラス ライブラリ名前空間 を参照しますSystem::Data::SqlClient

SqlDataAdapter オブジェクトとプロパティ

オブジェクトの InsertCommandSqlDataAdapter プロパティUpdateCommand、、および DeleteCommand プロパティは、オブジェクトで実行されるデータ変更を使用してデータベースをDataSet更新するために使用されます。 これらの各プロパティは、 SqlCommand ターゲット データベースに変更を投稿するために使用される、それぞれの INSERTUPDATE、および DELETE TSQL コマンドを DataSet 指定するオブジェクトです。 これらのプロパティに割り当てられたオブジェクトは SqlCommand 、コード内で手動で作成することも、オブジェクトを使用 SqlCommandBuilder して自動的に生成することもできます。

この記事の最初のコード サンプルでは、オブジェクトを使用してオブジェクトの SqlCommandBuilder プロパティを自動的に生成する UpdateCommand 方法を SqlDataAdapter 示します。 2 番目のサンプルでは、自動コマンド生成を使用できないシナリオを使用するため、オブジェクトのプロパティとしてオブジェクトを手動で作成して使用SqlCommandできるプロセスをUpdateCommandSqlDataAdapter示します。

サンプル SQL Server テーブルを作成する

この記事に記載されている Visual C++ .NET コード サンプルで使用するサンプル SQL Server テーブルを作成するには、次の手順に従います。

  1. クエリ アナライザー SQL Server開き、サンプル テーブルを作成するデータベースに接続します。 この記事のコード サンプルでは、SQL Serverに付属する Northwind データベースを使用します。

  2. 次の T-SQL ステートメントを実行して CustTest というサンプル テーブルを作成し、それにレコードを挿入します。

    Create Table CustTest
    (
        CustID int primary key,
        CustName varchar(20)
    )
    Insert into CustTest values(1,'John')
    

コード サンプル 1: 自動生成されたコマンド

SELECTを設定DataSetするために使用するデータを取得するステートメントが単一のデータベース テーブルに基づいている場合は、オブジェクトをCommandBuilder利用して、 の プロパティ、InsertCommand、および UpdateCommand プロパティをDataAdapter自動的に生成DeleteCommandできます。 これにより、および 操作を実行INSERTUPDATEするために必要なコードが簡略化され、DELETE削減されます。

最小要件として、コマンドの自動生成を SelectCommand 機能させるには、 プロパティを設定する必要があります。 によって取得されるテーブル スキーマによって SelectCommand 、自動的に生成される INSERT、、 UPDATEおよび ステートメントの構文が DELETE 決まります。

SelectCommand 、少なくとも 1 つの主キーまたは一意の列も返す必要があります。 存在しない場合は例外 InvalidOperation が生成され、コマンドは生成されません。

オブジェクトを使用SqlCommandBuilderして、オブジェクトの 、DeleteCommand、および UpdateCommand SqlCommand オブジェクトのプロパティを自動的に生成InsertCommandする方法を示すサンプル Visual C++ .NET コンソール アプリケーションをSqlDataAdapter作成するには、次の手順に従います。

  1. Visual Studio .NET を起動し、新しいマネージド C++ アプリケーションを作成します。 updateSQL という名前を付けます

  2. 次のコードをコピーして updateSQL.cpp に貼り付けます (既定の内容を置き換えます)。

    #include "stdafx.h"
    
    #using < mscorlib.dll>
    #using < System.dll>
    #using < System.Data.dll>
    #using < System.Xml.dll>
    
    using namespace System;
    using namespace System::Data;
    using namespace System::Data::SqlClient;
    
    #ifdef _UNICODE
        int wmain(void)
    #else
        int main(void)
    #endif
    {
        SqlConnection *cn = new SqlConnection();
        DataSet *CustomersDataSet = new DataSet();
        SqlDataAdapter *da;
        SqlCommandBuilder *cmdBuilder;
    
        //Set the connection string of the SqlConnection object to connect
        //to the SQL Server database in which you created the sample
        //table in Section 1.0
        cn->ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
        cn->Open();
    
        //Initialize the SqlDataAdapter object by specifying a Select command
        //that retrieves data from the sample table
        da = new SqlDataAdapter("select * from CustTest order by CustId", cn);
    
        //Initialize the SqlCommandBuilder object to automatically generate and initialize
        //the UpdateCommand, InsertCommand and DeleteCommand properties of the SqlDataAdapter
        cmdBuilder = new SqlCommandBuilder(da);
    
        //Populate the DataSet by executing the Fill method of the SqlDataAdapter
        da->Fill(CustomersDataSet, "Customers");
    
        //Display the Update, Insert and Delete commands that were automatically generated
        //by the SqlCommandBuilder object
        Console::WriteLine("Update command Generated by the Command Builder : ");
        Console::WriteLine("==================================================");
        Console::WriteLine(cmdBuilder->GetUpdateCommand()->CommandText);
        Console::WriteLine(" ");
        Console::WriteLine("Insert command Generated by the Command Builder : ");
        Console::WriteLine("==================================================");
        Console::WriteLine(cmdBuilder->GetInsertCommand()->CommandText);
        Console::WriteLine(" ");
        Console::WriteLine("Delete command Generated by the Command Builder : ");
        Console::WriteLine("==================================================");
        Console::WriteLine(cmdBuilder->GetDeleteCommand()->CommandText);
        Console::WriteLine(" ");
    
        //Write out the value in the CustName field before updating the data using the DataSet
        DataRow *rowCust = CustomersDataSet->Tables->Item["Customers"]->Rows->Item[0];
        Console::WriteLine("Customer Name before Update : {0} ", rowCust->Item["CustName"]);
    
        //Modify the value of the CustName field
        String *newStrVal = new String("Jack");
        rowCust->set_Item("CustName", newStrVal);
    
        //Modify the value of the CustName field again
        String *newStrVal2 = new String("Jack2");
        rowCust->set_Item("CustName", newStrVal2);
    
        //Post the data modification to the database
        da->Update(CustomersDataSet, "Customers");
    
        Console::WriteLine("Customer Name after Update : {0} ", rowCust->Item["CustName"]);
    
        //Close the database connection
        cn->Close();
    
        //Pause
        Console::ReadLine();
        return 0;
    }
    
  3. 手順 2 でコピーして貼り付けたコードで、次のように接続文字列コードの行を変更して、SQL Server コンピューターに正しく接続します。

    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    

    このコードを実行した後、SQL Serverインストールに接続してからサインインできます。

  4. アプリケーションを保存して実行します。 コンソール ウィンドウが開き、次の出力が表示されます。

    Update command generated by the Command Builder:
    ==================================================
    UPDATE CustTest SET CustID = @p1 , CustName = @p2 WHERE ( (CustID = @p3)
    AND ((CustName IS NULL AND @p4 IS NULL)
    OR (CustName = @p5)))
    Insert command generated by the Command Builder :
    ==================================================
    INSERT INTO CustTest( CustID , CustName ) VALUES ( @p1 , @p2 )
    Delete command generated by the Command Builder :
    ==================================================
    DELETE FROM CustTest WHERE ( (CustID = @p1)
    AND ((CustName IS NULL AND @p2 IS NULL)
    OR (CustName = @p3)))
    Customer Name before Update : John
    Customer Name after Update : Jack2
    
  5. 任意のキーを押してコンソール ウィンドウを閉じ、アプリケーションを停止します。

コード サンプル 2: UpdateCommand プロパティを手動で作成して初期化する

コード サンプル 1 によって生成される出力は、ステートメントに対 UPDATE してコマンドを自動的に生成するためのロジックが オプティミスティック コンカレンシーに基づいていることを示します。 つまり、レコードは編集のためにロックされず、他のユーザーまたはプロセスによっていつでも変更できます。 レコードはステートメントから SELECT 返された後、ステートメントが発行される前に UPDATE 変更された可能性があるため、自動的に生成される UPDATE ステートメントには句が含 WHERE まれ、元のすべての値が含まれ、削除されていない場合にのみ行が更新されます。 これは、新しいデータが上書きされないようにするために行われます。 で検出 DataSetされた元の値が含まれていない、または削除された行を自動的に生成された更新が試みる場合、コマンドはどのレコードにも影響せず、 DBConcurrencyException がスローされます。

元の値に関係なく をUPDATE完了する場合は、自動コマンド生成に依存するのではなく、 DataAdapter の をUpdateCommand明示的に設定する必要があります。

コード サンプル 1 で使用するオブジェクトのプロパティをUpdateCommandSqlDataAdapter手動で作成して初期化するには、次の手順に従います。

  1. コード サンプル 1 で作成した C++ アプリケーションのUpdateSQL.cpp ファイル内の関数にMain()、次のコードをコピーして貼り付けます (既存のコードを上書きします)。

    SqlConnection *cn = new SqlConnection();
    DataSet *CustomersDataSet = new DataSet();
    SqlDataAdapter *da;
    SqlCommand *DAUpdateCmd;
    cn->ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    cn->Open();
    da = new SqlDataAdapter("select * from CustTest order by CustId", cn);
    
    //Initialize the SqlCommand object that will be used as the DataAdapter's UpdateCommand
    //Notice that the WHERE clause uses only the CustId field to locate the record to be updated
    DAUpdateCmd = new SqlCommand("Update CustTest set CustName = @pCustName where CustId = @pCustId"
    , da->SelectCommand->Connection);
    
    //Create and append the parameters for the Update command
    DAUpdateCmd->Parameters->Add(new SqlParameter("@pCustName", SqlDbType::VarChar));
    DAUpdateCmd->Parameters->Item["@pCustName"]->SourceVersion = DataRowVersion::Current;
    DAUpdateCmd->Parameters->Item["@pCustName"]->SourceColumn = "CustName";
    
    DAUpdateCmd->Parameters->Add(new SqlParameter("@pCustId", SqlDbType::Int));
    DAUpdateCmd->Parameters->Item["@pCustId"]->SourceVersion = DataRowVersion::Original;
    DAUpdateCmd->Parameters->Item["@pCustId"]->SourceColumn = "CustId";
    
    //Assign the SqlCommand to the UpdateCommand property of the SqlDataAdapter
    da->UpdateCommand = DAUpdateCmd;
    da->Fill(CustomersDataSet, "Customers");
    
    DataRow *rowCust = CustomersDataSet->Tables->Item["Customers"]->Rows->Item[0];
    Console::WriteLine("Customer Name before Update : {0} ", rowCust->Item["CustName"]);
    
    //Modify the value of the CustName field
    String *newStrVal = new String("Jack");
    rowCust->set_Item("CustName", newStrVal);
    
    //Modify the value of the CustName field again
    String *newStrVal2 = new String("Jack2");
    rowCust->set_Item("CustName", newStrVal2);
    
    da->Update(CustomersDataSet, "Customers");
    Console::WriteLine("Customer Name after Update : {0} ", rowCust->Item["CustName"]);
    cn->Close();
    Console::ReadLine();
    return 0;
    
  2. 前のコード サンプルの接続文字列コード行を次のように変更します。

    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    
  3. この記事のコード サンプル 1 セクションのコードを既に実行している場合は、SQL Serverで CustTestテーブルを開き、最初のレコードの CustName 値を John に変更します。

  4. アプリケーションを保存して実行します。 コンソール ウィンドウが開き、次の出力が表示されます。

    Customer Name before Update : John
    Customer Name after Update : Jack2