次の方法で共有


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

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

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

まとめ

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

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

この記事では、.NET Framework クラス ライブラリ名前空間 System::Data::SqlClientについて説明します。

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

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

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

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

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

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

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

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

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

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

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

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

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

  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を完了する場合は、コマンドの自動生成に依存するのではなく、DataAdapterUpdateCommandを明示的に設定する必要があります。

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

  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. この記事の code サンプル 1 セクションのコードを既に実行している場合は、SQL Server で CustTesttable を開き、最初のレコードの CustName 値を John に戻します。

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

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