Visual C++에서 SqlDataAdapter 개체를 사용하여 SQL Server 데이터베이스 업데이트

이 문서에서는 개체를 사용하여 SqlDataAdapter Microsoft Visual C++ SQL Server 데이터베이스를 업데이트하는 방법을 소개합니다.

원래 제품 버전: Visual C++
원본 KB 번호: 308510

요약

개체는 SqlDataAdapter ADO.NET 개체와 SQL Server DataSet 데이터베이스 간의 브리지 역할을 합니다. 다음을 수행하는 데 사용할 수 있는 중간 개체입니다.

  • SQL Server DataSet 데이터베이스에서 검색된 데이터로 ADO.NET 채웁다.
  • 를 사용하여 데이터에 대한 변경 내용(삽입, 업데이트, 삭제)을 반영하도록 데이터베이스를 DataSet업데이트합니다. 이 문서에서는 개체를 사용하여 데이터베이스에 있는 테이블의 SqlDataAdapter 데이터로 채워진 개체에서 DataSet 실행된 데이터 수정으로 SQL Server 데이터베이스를 업데이트하는 방법을 보여 주는 Visual C++ .NET 코드 샘플을 제공합니다.

이 문서에서는 .NET Framework 클래스 라이브러리 네임스페이스 를 참조합니다System::Data::SqlClient.

SqlDataAdapter 개체 및 속성

InsertCommand개체의 SqlDataAdapter , UpdateCommandDeleteCommand 속성은 개체에서 실행된 DataSet 데이터 수정으로 데이터베이스를 업데이트하는 데 사용됩니다. 이러한 각 속성은 SqlCommand 대상 데이터베이스에 수정 내용을 게시 DataSet 하는 데 사용되는 각 INSERT, UPDATEDELETE TSQL 명령을 지정하는 개체입니다. 이러한 속성에 할당된 개체는 SqlCommand 코드에서 수동으로 만들거나 개체를 사용하여 SqlCommandBuilder 자동으로 생성될 수 있습니다.

이 문서의 첫 번째 코드 샘플에서는 개체를 SqlCommandBuilder 사용하여 개체의 SqlDataAdapter 속성을 자동으로 생성하는 UpdateCommand 방법을 보여 줍니다. 두 번째 샘플에서는 자동 명령 생성을 사용할 수 없는 시나리오를 사용하므로 개체를 수동으로 만들고 개체의 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: 자동으로 생성된 명령

SELECT 를 채우는 DataSet 데 사용되는 데이터를 검색하는 문이 단일 데이터베이스 테이블을 기반으로 하는 경우 개체를 CommandBuilder 활용하여 의 DataAdapter, InsertCommandUpdateCommand 속성을 자동으로 생성DeleteCommand할 수 있습니다. 이렇게 하면 , UPDATE및 작업을 수행하는 INSERT데 필요한 코드가 간소화되고 DELETE 줄어듭니다.

최소 요구 사항으로 자동 명령 생성이 SelectCommand 작동하도록 속성을 설정해야 합니다. 에 의해 SelectCommand 검색되는 테이블 스키마는 자동으로 생성된 INSERT, UPDATEDELETE 문의 구문을 결정합니다.

또한 는 SelectCommand 하나 이상의 기본 키 또는 고유 열을 반환해야 합니다. 없는 InvalidOperation 경우 예외가 생성되고 명령이 생성되지 않습니다.

개체를 사용하여 SqlCommandBuilder 개체에 대한 , DeleteCommandUpdateCommand SqlCommand 개체 속성을 자동으로 생성하는 InsertCommand방법을 보여 주는 샘플 Visual C++ .NET 콘솔 애플리케이션을 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 throw됩니다.

원래 값에 관계없이 를 UPDATE 완료하려면 자동 명령 생성에 의존하지 않고 에 대해 을 DataAdapter 명시적으로 설정 UpdateCommand 해야 합니다.

코드 샘플 1에 사용되는 개체의 SqlDataAdapter 속성을 수동으로 만들고 초기화 UpdateCommand 하려면 다음 단계를 수행합니다.

  1. 코드 샘플 1에서 Main() 만든 C++ 애플리케이션의 UpdateSQL.cpp 파일 내 함수에 다음 코드(기존 코드 덮어쓰기)를 복사하여 붙여넣습니다.

    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 섹션에서 코드를 이미 실행한 경우 SQL Server CustTest테이블을 연 다음 첫 번째 레코드의 CustName 값을 John으로 다시 변경합니다.

  4. 애플리케이션을 저장하고 실행합니다. 콘솔 창이 열리고 다음 출력이 표시됩니다.

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