Atualizar um banco de dados SQL Server usando o objeto SqlDataAdapter no Visual C++

Este artigo apresenta como usar o SqlDataAdapter objeto para atualizar um banco de dados SQL Server no Microsoft Visual C++.

Versão original do produto: Visual C++
Número original do KB: 308510

Resumo

O SqlDataAdapter objeto serve como uma ponte entre um objeto ADO.NET DataSet e um banco de dados SQL Server. É um objeto intermediário que você pode usar para fazer o seguinte:

  • Preencha um ADO.NET DataSet com dados recuperados de um banco de dados SQL Server.
  • Atualize o banco de dados para refletir as alterações (inserções, atualizações, exclusões) feitas aos dados usando o DataSet. Este artigo fornece exemplos de código .NET do Visual C++ para demonstrar como o SqlDataAdapter objeto pode ser usado para atualizar um banco de dados SQL Server com modificações de dados executadas em um DataSet objeto que é preenchido com dados de uma tabela no banco de dados.

Este artigo refere-se ao namespace System::Data::SqlClientda Biblioteca de Classes .NET Framework .

Propriedades e objeto SqlDataAdapter

As InsertCommandpropriedades , UpdateCommande DeleteCommand do SqlDataAdapter objeto são usadas para atualizar o banco de dados com as modificações de dados executadas em um DataSet objeto. Cada uma dessas propriedades são SqlCommand objetos que especificam os respectivos INSERTcomandos , UPDATEe DELETE TSQL usados para postar as DataSet modificações no banco de dados de destino. Os SqlCommand objetos atribuídos a essas propriedades podem ser criados manualmente no código ou podem ser gerados automaticamente usando o SqlCommandBuilder objeto.

O primeiro exemplo de código neste artigo demonstra como o SqlCommandBuilder objeto pode ser usado para gerar automaticamente a UpdateCommand propriedade do SqlDataAdapter objeto. O segundo exemplo usa um cenário no qual a geração automática de comandos não pode ser usada e, portanto, demonstra o processo pelo qual você pode criar e usar manualmente um SqlCommand objeto como propriedade UpdateCommand de um SqlDataAdapter objeto.

Criar a tabela SQL Server de exemplo

Para criar um exemplo SQL Server tabela a ser usada nos exemplos de código .NET do Visual C++ documentados neste artigo, siga estas etapas:

  1. Abra SQL Server Analisador de Consultas e conecte-se a um banco de dados no qual você deseja criar a tabela de exemplo. Os exemplos de código neste artigo usam o banco de dados Northwind que vem com SQL Server.

  2. Execute as seguintes instruções T-SQL para criar uma tabela de exemplo chamada CustTest e insira um registro nela.

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

Exemplo de código 1: comandos gerados automaticamente

Se a SELECT instrução para recuperar os dados usados para preencher um DataSet for baseada em uma única tabela de banco de dados, você poderá aproveitar o CommandBuilder objeto para gerar automaticamente as DeleteCommandpropriedades , InsertCommande UpdateCommand do DataAdapter. Isso simplifica e reduz o código necessário para executar INSERT, UPDATEe DELETE operações.

Como um requisito mínimo, você deve definir a propriedade para que SelectCommand a geração de comandos automática funcione. O esquema de tabela recuperado pelo SelectCommand determina a sintaxe das instruções , UPDATEe DELETE geradas INSERTautomaticamente.

O SelectCommand também deve retornar pelo menos uma chave primária ou uma coluna exclusiva. Se nenhum estiver presente, uma exceção InvalidOperation será gerada e os comandos não serão gerados.

Para criar um aplicativo de console .NET do Visual C++ que demonstra como usar o SqlCommandBuilder objeto para gerar automaticamente as InsertCommandpropriedades do objeto , DeleteCommande UpdateCommand SqlCommand para um SqlDataAdapter objeto, siga estas etapas:

  1. Inicie o Visual Studio .NET e crie um novo aplicativo C++ gerenciado. Nomeie-o updateSQL.

  2. Copie e cole o seguinte código no updateSQL.cpp (substituindo seu conteúdo padrão):

    #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. No código copiado e colado na etapa 2, modifique a linha do código de cadeia de caracteres de conexão para se conectar corretamente ao computador SQL Server, da seguinte maneira:

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

    Depois de executar esse código, você pode se conectar com o SQL Server instalação e entrar.

  4. Salve e execute o aplicativo. Uma janela do console será aberta e exibirá a seguinte saída:

    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. Pressione qualquer tecla para descartar a janela do console e parar o aplicativo.

Exemplo de código 2: criar e inicializar manualmente a propriedade UpdateCommand

A saída gerada pelo exemplo de código 1 indica que a lógica para gerar comandos automaticamente para UPDATE instruções se baseia na simultaneidade otimista. Ou seja, os registros não são bloqueados para edição e podem ser modificados por outros usuários ou processos a qualquer momento. Como um registro pode ter sido modificado depois que ele foi retornado da SELECT instrução, mas antes da UPDATE instrução ser emitida, a instrução gerada UPDATE automaticamente contém uma WHERE cláusula para que uma linha seja atualizada somente se ela contiver todos os valores originais e não tiver sido excluída. Isso é feito para garantir que novos dados não sejam substituídos. Nos casos em que uma atualização gerada automaticamente tenta atualizar uma linha que foi excluída ou não contém os valores originais encontrados no DataSet, o comando não afeta nenhum registro e um DBConcurrencyException é lançado.

Se você quiser concluir UPDATE independentemente dos valores originais, precisará definir explicitamente o UpdateCommand para o em vez de depender da DataAdapter geração de comando automática.

Para criar e inicializar manualmente a UpdateCommand propriedade do SqlDataAdapter objeto usado no exemplo de código 1, siga estas etapas:

  1. Copie e cole o seguinte código (substituindo o código existente) na Main() função dentro do arquivo UpdateSQL.cpp no aplicativo C++ criado no exemplo de código 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. Modifique a linha do código de cadeia de caracteres de conexão no exemplo de código anterior da seguinte maneira:

    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    
  3. Se você já tiver executado o código na seção de exemplo de código 1 deste artigo, abra sua tabela CustTestem SQL Server e altere o valor custName no primeiro registro de volta para John.

  4. Salve e execute o aplicativo. Uma janela do console será aberta e exibirá a seguinte saída:

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