Обновление базы данных SQL Server с помощью объекта SqlDataAdapter в Visual C++
В этой статье описывается, как использовать SqlDataAdapter
объект для обновления базы данных SQL Server в Microsoft Visual C++.
Исходная версия продукта: Visual C++
Оригинальный номер базы знаний: 308510
Сводка
Объект SqlDataAdapter
служит мостом между объектом ADO.NET DataSet
и SQL Server базой данных. Это промежуточный объект, который можно использовать для выполнения следующих действий:
- Заполните ADO.NET
DataSet
данными, полученными из базы данных SQL Server. - Обновите базу данных, чтобы отразить изменения (вставки, обновления, удаления), внесенные в данные, с помощью
DataSet
. В этой статье приведены примеры кода .NET для Visual C++, демонстрирующие, какSqlDataAdapter
можно использовать объект для обновления SQL Server базы данных с изменениями данных, выполненными в объектеDataSet
, заполненном данными из таблицы в базе данных.
В этой статье описывается пространство System::Data::SqlClient
имен библиотеки классов платформа .NET Framework .
Объект и свойства SqlDataAdapter
Свойства InsertCommand
SqlDataAdapter
, UpdateCommand
и DeleteCommand
объекта используются для обновления базы данных с изменениями данных, выполненными в объекте DataSet
. Каждое из этих свойств является SqlCommand
объектами, указывающими соответствующие INSERT
команды , UPDATE
и DELETE
TSQL, используемые для публикации DataSet
изменений в целевой базе данных. Объекты, назначенные SqlCommand
этим свойствам, могут создаваться вручную в коде SqlCommandBuilder
или автоматически создаваться с помощью объекта .
В первом примере кода в этой статье показано, как SqlCommandBuilder
объект можно использовать для автоматического UpdateCommand
SqlDataAdapter
создания свойства объекта . Во втором примере используется сценарий, в котором невозможно использовать автоматическое создание команд, и поэтому демонстрируется процесс, с помощью которого можно вручную создать и использовать SqlCommand
объект в UpdateCommand
качестве свойства SqlDataAdapter
объекта.
Создание примера таблицы SQL Server
Чтобы создать пример SQL Server таблицы для использования в примерах кода .NET для Visual C++, описанных в этой статье, выполните следующие действия.
Откройте SQL Server анализатора запросов, а затем подключитесь к базе данных, в которой вы хотите создать пример таблицы. В примерах кода, приведенных в этой статье, используется база данных Northwind, которая поставляется с SQL Server.
Выполните следующие инструкции T-SQL, чтобы создать пример таблицы CustTest, а затем вставить в нее запись.
Create Table CustTest ( CustID int primary key, CustName varchar(20) ) Insert into CustTest values(1,'John')
Пример кода 1. Автоматически созданные команды
SELECT
Если инструкция для получения данных, используемых для заполненияDataSet
, основана на отдельной таблице базы данных, вы можете воспользоваться преимуществами объекта для автоматического DeleteCommand
CommandBuilder
создания свойств DataAdapter
, InsertCommand
и UpdateCommand
объекта . Это упрощает и уменьшает код, необходимый для выполнения INSERT
операций , UPDATE
и DELETE
.
В качестве минимального требования необходимо задать SelectCommand
свойство для работы автоматического создания команд. Схема таблицы, полученная с SelectCommand
помощью , определяет синтаксис автоматически созданных INSERT
инструкций , UPDATE
и DELETE
.
Также SelectCommand
должен возвращать по крайней мере один первичный ключ или уникальный столбец. Если нет, InvalidOperation
создается исключение, а команды не создаются.
Чтобы создать пример консольного приложения .NET visual C++, демонстрирующего SqlCommandBuilder
использование объекта для автоматического InsertCommand
создания свойств объекта , DeleteCommand
и UpdateCommand
SqlCommand для SqlDataAdapter
объекта, выполните следующие действия:
Запустите 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
завершить независимо от исходных значений, необходимо явно задать UpdateCommand
для DataAdapter
, а не полагаться на автоматическое создание команд.
Чтобы вручную создать и инициализировать UpdateCommand
свойство объекта, используемого SqlDataAdapter
в примере кода 1, выполните следующие действия.
Скопируйте и вставьте следующий код (перезапись существующего кода) в функцию
Main()
в файле UpdateSQL.cpp в приложении C++, созданном в примере кода 1: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;";
Если вы уже выполнили код в примере кода 1 этой статьи, откройте таблицу CustTestв SQL Server, а затем измените значение CustName в первой записи на John.
Сохраните и выполните приложение. Откроется окно консоли, в котором отображаются следующие выходные данные:
Customer Name before Update : John Customer Name after Update : Jack2
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по