Обновление базы данных 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

Свойства InsertCommandSqlDataAdapter , UpdateCommandи DeleteCommand объекта используются для обновления базы данных с изменениями данных, выполненными в объекте DataSet . Каждое из этих свойств является SqlCommand объектами, указывающими соответствующие INSERTкоманды , UPDATEи DELETE TSQL, используемые для публикации DataSet изменений в целевой базе данных. Объекты, назначенные SqlCommand этим свойствам, могут создаваться вручную в коде SqlCommandBuilder или автоматически создаваться с помощью объекта .

В первом примере кода в этой статье показано, как SqlCommandBuilder объект можно использовать для автоматического UpdateCommandSqlDataAdapter создания свойства объекта . Во втором примере используется сценарий, в котором невозможно использовать автоматическое создание команд, и поэтому демонстрируется процесс, с помощью которого можно вручную создать и использовать SqlCommand объект в UpdateCommand качестве свойства SqlDataAdapter объекта.

Создание примера таблицы SQL Server

Чтобы создать пример SQL Server таблицы для использования в примерах кода .NET для Visual C++, описанных в этой статье, выполните следующие действия.

  1. Откройте SQL Server анализатора запросов, а затем подключитесь к базе данных, в которой вы хотите создать пример таблицы. В примерах кода, приведенных в этой статье, используется база данных Northwind, которая поставляется с SQL Server.

  2. Выполните следующие инструкции T-SQL, чтобы создать пример таблицы CustTest, а затем вставить в нее запись.

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

Пример кода 1. Автоматически созданные команды

SELECT Если инструкция для получения данных, используемых для заполненияDataSet, основана на отдельной таблице базы данных, вы можете воспользоваться преимуществами объекта для автоматического DeleteCommandCommandBuilder создания свойств DataAdapter, InsertCommandи UpdateCommand объекта . Это упрощает и уменьшает код, необходимый для выполнения INSERTопераций , UPDATEи DELETE .

В качестве минимального требования необходимо задать SelectCommand свойство для работы автоматического создания команд. Схема таблицы, полученная с SelectCommand помощью , определяет синтаксис автоматически созданных INSERTинструкций , UPDATEи DELETE .

Также SelectCommand должен возвращать по крайней мере один первичный ключ или уникальный столбец. Если нет, InvalidOperation создается исключение, а команды не создаются.

Чтобы создать пример консольного приложения .NET visual C++, демонстрирующего SqlCommandBuilder использование объекта для автоматического InsertCommandсоздания свойств объекта , DeleteCommandи UpdateCommand SqlCommand для 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 завершить независимо от исходных значений, необходимо явно задать UpdateCommand для DataAdapter , а не полагаться на автоматическое создание команд.

Чтобы вручную создать и инициализировать UpdateCommand свойство объекта, используемого SqlDataAdapter в примере кода 1, выполните следующие действия.

  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;
    
  2. Измените строку кода строки подключения в предыдущем примере кода следующим образом:

    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    
  3. Если вы уже выполнили код в примере кода 1 этой статьи, откройте таблицу CustTestв SQL Server, а затем измените значение CustName в первой записи на John.

  4. Сохраните и выполните приложение. Откроется окно консоли, в котором отображаются следующие выходные данные:

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