この記事では、 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
オブジェクトのInsertCommand
、UpdateCommand
、およびDeleteCommand
プロパティは、DataSet
オブジェクトで実行されたデータ変更でデータベースを更新するために使用されます。 これらの各プロパティはSqlCommand
オブジェクトであり、ターゲット データベースにDataSet
の変更を投稿するために使用する、それぞれのINSERT
、UPDATE
、およびDELETE
TSQL コマンドを指定します。 これらのプロパティに割り当てられた SqlCommand
オブジェクトは、コードで手動で作成することも、 SqlCommandBuilder
オブジェクトを使用して自動的に生成することもできます。
この記事の最初のコード サンプルでは、SqlCommandBuilder
オブジェクトを使用して、SqlDataAdapter
オブジェクトのUpdateCommand
プロパティを自動的に生成する方法を示します。 2 番目のサンプルでは、コマンドの自動生成を使用できないシナリオを使用するため、SqlDataAdapter
オブジェクトのUpdateCommand
プロパティとしてSqlCommand
オブジェクトを手動で作成して使用できるプロセスを示します。
サンプル SQL Server テーブルを作成する
この記事に記載されている Visual C++ .NET コード サンプルで使用するサンプル SQL Server テーブルを作成するには、次の手順に従います。
SQL Server Query Analyzer を開き、サンプル テーブルを作成するデータベースに接続します。 この記事のコード サンプルでは、SQL Server に付属する Northwind データベースを使用します。
次の T-SQL ステートメントを実行して、 CustTest というサンプル テーブルを作成し、それにレコードを挿入します。
Create Table CustTest ( CustID int primary key, CustName varchar(20) ) Insert into CustTest values(1,'John')
コード サンプル 1: 自動生成されたコマンド
DataSet
の設定に使用するデータを取得するSELECT
ステートメントが単一のデータベース テーブルに基づいている場合は、CommandBuilder
オブジェクトを利用して、DataAdapter
のDeleteCommand
、InsertCommand
、およびUpdateCommand
プロパティを自動的に生成できます。 これにより、 INSERT
、 UPDATE
、および DELETE
操作を実行するために必要なコードが簡略化され、削減されます。
最小要件として、コマンドの自動生成を機能させるには、 SelectCommand
プロパティを設定する必要があります。 SelectCommand
によって取得されるテーブル スキーマによって、自動的に生成されるINSERT
、UPDATE
、およびDELETE
ステートメントの構文が決まります。
SelectCommand
は少なくとも 1 つの主キーまたは一意の列を返す必要があります。 1 つも存在しない場合は、InvalidOperation
例外が生成され、コマンドは生成されません。
SqlCommandBuilder
オブジェクトを使用して、SqlDataAdapter
オブジェクトの sqlCommand オブジェクト プロパティのInsertCommand
、DeleteCommand
、およびUpdateCommand
を自動的に生成する方法を示す Visual C++ .NET コンソール アプリケーションのサンプルを作成するには、次の手順に従います。
Visual Studio .NET を起動し、新しいマネージド C++ アプリケーションを作成します。 updateSQL名前を付けます。
次のコードをコピーして 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; }
手順 2 でコピーして貼り付けたコードで、次のように接続文字列コードの行を変更して、SQL Server コンピューターに正しく接続します。
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
このコードを実行した後、SQL Server のインストールに接続してからサインインできます。
アプリケーションを保存して実行します。 コンソール ウィンドウが開き、次の出力が表示されます。
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
任意のキーを押してコンソール ウィンドウを閉じ、アプリケーションを停止します。
コード サンプル 2: UpdateCommand プロパティを手動で作成して初期化する
コード サンプル 1 によって生成される出力は、 UPDATE
ステートメントのコマンドを自動的に生成するロジックが、最適なコンカレンシー 基づいてことを示します。 つまり、レコードは編集用にロックされず、他のユーザーまたはプロセスによっていつでも変更できます。 レコードは、 SELECT
ステートメントから返された後、 UPDATE
ステートメントが発行される前に変更された可能性があるため、自動的に生成された UPDATE
ステートメントには WHERE
句が含まれているため、元の値がすべて含まれ、削除されていない場合にのみ行が更新されます。 これは、新しいデータが上書きされないようにするために行われます。 自動的に生成された更新で、削除された行、または DataSet
で見つかった元の値が含まれていない行の更新が試行された場合、コマンドはレコードに影響を与えず、 DBConcurrencyException
がスローされます。
元の値に関係なくUPDATE
を完了する場合は、コマンドの自動生成に依存するのではなく、DataAdapter
のUpdateCommand
を明示的に設定する必要があります。
コード サンプル 1 で使用するSqlDataAdapter
オブジェクトのUpdateCommand
プロパティを手動で作成して初期化するには、次の手順に従います。
コード サンプル 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;
前のコード サンプルの接続文字列コード行を次のように変更します。
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
この記事の code サンプル 1 セクションのコードを既に実行している場合は、SQL Server で CustTesttable を開き、最初のレコードの CustName 値を John に戻します。
アプリケーションを保存して実行します。 コンソール ウィンドウが開き、次の出力が表示されます。
Customer Name before Update : John Customer Name after Update : Jack2