다음을 통해 공유


단일 대량 복사 작업

ADO.NET 다운로드

SQL Server 대량 복사 작업을 수행하는 가장 간단한 접근 방식은 데이터베이스에 단일 작업을 수행하는 것입니다. 기본적으로 대량 복사 작업은 격리된 작업으로 수행됩니다. 복사 작업은 트랜잭션되지 않은 방식으로 수행되어 롤백할 수 없습니다.

참고 항목

오류가 발생할 때 대량 복사의 전체 또는 일부를 롤백해야 하는 경우에는 SqlBulkCopy에서 관리되는 트랜잭션을 사용하거나 기존 트랜잭션 내에서 대량 복사 작업을 수행할 수 있습니다. 연결이 System.Transactions 트랜잭션에 암시적으로나 명시적으로 인리스트먼트된 경우 SqlBulkCopy에서도 System.Transactions를 사용합니다.

자세한 내용은 트랜잭션 및 대량 복사 작업을 참조하세요.

대량 복사 작업을 수행하는 일반적인 단계는 다음과 같습니다.

  1. 소스 서버에 연결하고 복사할 데이터를 가져옵니다. IDataReader 또는 DataTable 개체에서 데이터를 검색할 수 있는 경우, 다른 원본에서 데이터를 가져올 수도 있습니다.

  2. SqlBulkCopy를 통해 자동으로 연결하지 않으려는 경우 대상 서버에 연결합니다.

  3. 필요한 속성을 설정하면서 SqlBulkCopy 개체를 만듭니다.

  4. DestinationTableName 속성이 대량 삽입 작업의 대상 테이블을 나타내도록 설정합니다.

  5. writeToServer 메서드 중 하나를 호출합니다.

  6. 필요에 따라 속성을 업데이트하고 WriteToServer를 다시 호출합니다.

  7. Close를 호출하거나 대량 복사 작업을 Using 문 내에 래핑합니다.

주의

소스 열과 대상 열의 데이터 형식은 일치하는 것이 좋습니다. 데이터 형식이 일치하지 않으면 SqlBulkCopyValue에서 사용되는 규칙과 동일한 규칙을 사용하여 각 소스 값을 대상 데이터 형식으로 변환하려고 시도합니다. 변환을 수행하면 성능에 영향을 줄 뿐 아니라 예기치 않은 오류가 발생할 수도 있습니다. 예를 들어 Double 데이터 형식은 대부분의 경우 Decimal 데이터 형식으로 변환할 수 있지만 항상 그렇지는 않습니다.

예시

다음 콘솔 애플리케이션에서는 SqlBulkCopy 클래스를 사용하여 데이터를 로드하는 방법을 보여 줍니다. 이 예제에서는 SqlDataReader를 사용하여 SQL Server AdventureWorks 데이터베이스에 있는 Production.Product 테이블의 데이터를 같은 데이터베이스의 비슷한 테이블로 복사합니다.

Important

이 샘플은 가져올 대량 복사 샘플 설정에 설명된 대로 작업 테이블을 만들지 않은 경우 실행되지 않습니다. 이 코드는 SqlBulkCopy를 사용하는 구문을 보여 주는 용도로 제공됩니다. 소스 테이블과 대상 테이블이 동일한 SQL Server 인스턴스에 있으면 Transact-SQL INSERT … SELECT 문을 사용하여 데이터를 더 쉽고 빠르게 복사할 수 있습니다.

using Microsoft.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connectionString = GetConnectionString();
        // Open a sourceConnection to the AdventureWorks database.
        using (SqlConnection sourceConnection =
                   new SqlConnection(connectionString))
        {
            sourceConnection.Open();

            // Perform an initial count on the destination table.
            SqlCommand commandRowCount = new SqlCommand(
                "SELECT COUNT(*) FROM " +
                "dbo.BulkCopyDemoMatchingColumns;",
                sourceConnection);
            long countStart = System.Convert.ToInt32(
                commandRowCount.ExecuteScalar());
            Console.WriteLine("Starting row count = {0}", countStart);

            // Get data from the source table as a SqlDataReader.
            SqlCommand commandSourceData = new SqlCommand(
                "SELECT ProductID, Name, " +
                "ProductNumber " +
                "FROM Production.Product;", sourceConnection);
            SqlDataReader reader =
                commandSourceData.ExecuteReader();

            // Open the destination connection. In the real world you would 
            // not use SqlBulkCopy to move data from one table to the other 
            // in the same database. This is for demonstration purposes only.
            using (SqlConnection destinationConnection =
                       new SqlConnection(connectionString))
            {
                destinationConnection.Open();

                // Set up the bulk copy object. 
                // Note that the column positions in the source
                // data reader match the column positions in 
                // the destination table so there is no need to
                // map columns.
                using (SqlBulkCopy bulkCopy =
                           new SqlBulkCopy(destinationConnection))
                {
                    bulkCopy.DestinationTableName =
                        "dbo.BulkCopyDemoMatchingColumns";

                    try
                    {
                        // Write from the source to the destination.
                        bulkCopy.WriteToServer(reader);
                        // Print the number of rows processed using the 
                        // RowsCopied property.
                        Console.WriteLine("{0} rows were processed.",
                            bulkCopy.RowsCopied);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    finally
                    {
                        // Close the SqlDataReader. The SqlBulkCopy
                        // object is automatically closed at the end
                        // of the using block.
                        reader.Close();
                    }
                }

                // Perform a final count on the destination 
                // table to see how many rows were added.
                long countEnd = System.Convert.ToInt32(
                    commandRowCount.ExecuteScalar());
                Console.WriteLine("Ending row count = {0}", countEnd);
                Console.WriteLine("{0} rows were added.", countEnd - countStart);
                Console.WriteLine("Press Enter to finish.");
                Console.ReadLine();
            }
        }
    }

    private static string GetConnectionString()
    // To avoid storing the sourceConnection string in your code, 
    // you can retrieve it from a configuration file. 
    {
        return "Data Source=(local); " +
            " Integrated Security=true;" +
            "Initial Catalog=AdventureWorks;";
    }
}

Transact-SQL 및 Command 클래스를 사용하여 대량 복사 작업 수행

다음 예제에서는 ExecuteNonQuery 메서드를 사용하여 BULK INSERT 문을 실행하는 방법을 보여 줍니다.

참고 항목

데이터 소스의 파일 경로는 서버에 대해 상대적입니다. 대량 복사 작업이 성공하려면 서버 프로세스에서 해당 경로에 액세스할 수 있어야 합니다.

using (SqlConnection connection = New SqlConnection(connectionString))  
{  
string queryString =  "BULK INSERT Northwind.dbo.[Order Details] " +  
    "FROM 'f:\mydata\data.tbl' " +  
    "WITH ( FORMATFILE='f:\mydata\data.fmt' )";  
connection.Open();  
SqlCommand command = new SqlCommand(queryString, connection);  
  
command.ExecuteNonQuery();  
}  

다음 단계