복붙노트

[SQL] 행으로 전체 데이터베이스에 DataTable을 한 번에 대신 행입니까?

SQL

행으로 전체 데이터베이스에 DataTable을 한 번에 대신 행입니까?

나는 DataTable에 있고 데이터베이스 테이블에 밀려 전체 일을해야합니다.

나는 그것이 모든 거기의 foreach와 한 번에 각 행을 삽입에서 얻을 수 있습니다. 수천 행이 때문에 비록 매우 느리게 간다.

즉 빠를 수도 한 번에 전체 데이터 테이블을 할 수있는 방법이 있습니까?

DataTable에는 SQL 테이블보다 열이 있습니다. 그 나머지는 NULL을 두어야합니다.

해결법

  1. ==============================

    1.나는 SqlBulkCopy의이 작업을 수행 할 수있는 가장 쉬운 방법이며, SQL 서버에 기록 될 수있는 저장 프로 시저를 필요로하지 않습니다 발견했다.

    나는 SqlBulkCopy의이 작업을 수행 할 수있는 가장 쉬운 방법이며, SQL 서버에 기록 될 수있는 저장 프로 시저를 필요로하지 않습니다 발견했다.

    여기에 내가 그것을 구현하는 방법의 예입니다 :

    // take note of SqlBulkCopyOptions.KeepIdentity , you may or may not want to use this for your situation.  
    
    using (var bulkCopy = new SqlBulkCopy(_connection.ConnectionString, SqlBulkCopyOptions.KeepIdentity))
    {
          // my DataTable column names match my SQL Column names, so I simply made this loop. However if your column names don't match, just pass in which datatable name matches the SQL column name in Column Mappings
          foreach (DataColumn col in table.Columns)
          {
              bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
          }
    
          bulkCopy.BulkCopyTimeout = 600;
          bulkCopy.DestinationTableName = destinationTableName;
          bulkCopy.WriteToServer(table);
    }
    
  2. ==============================

    2.이미 DataTable의를 가지고 있기 때문에, 나는 더 나은 SQL Server 2008 또는를 사용을 가정하고 있기 때문에, 이것은 아마도 가장 간단한 방법입니다. 먼저, 데이터베이스, 다음과 같은 두 개체를 만들 :

    이미 DataTable의를 가지고 있기 때문에, 나는 더 나은 SQL Server 2008 또는를 사용을 가정하고 있기 때문에, 이것은 아마도 가장 간단한 방법입니다. 먼저, 데이터베이스, 다음과 같은 두 개체를 만들 :

    CREATE TYPE dbo.MyDataTable -- you can be more speciifc here
    AS TABLE
    (
      col1 INT,
      col2 DATETIME
      -- etc etc. The columns you have in your data table.
    );
    GO
    
    CREATE PROCEDURE dbo.InsertMyDataTable
      @dt AS dbo.MyDataTable READONLY
    AS
    BEGIN
      SET NOCOUNT ON;
    
      INSERT dbo.RealTable(column list) SELECT column list FROM @dt;
    END
    GO
    

    이제 C # 코드에서 :

    DataTable tvp = new DataTable();
    // define / populate DataTable
    
    using (connectionObject)
    {
        SqlCommand cmd = new SqlCommand("dbo.InsertMyDataTable", connectionObject);
        cmd.CommandType = CommandType.StoredProcedure;
        SqlParameter tvparam = cmd.Parameters.AddWithValue("@dt", tvp);
        tvparam.SqlDbType = SqlDbType.Structured;
        cmd.ExecuteNonQuery();
    }
    

    당신이 당신의 질문에 좀 더 구체적인 정보를 제공 한 경우에, 나는 더 구체적인 대답을 준 것입니다.

  3. ==============================

    3.이 방법을 고려, 당신은 루프에 대한 필요가 없습니다

    이 방법을 고려, 당신은 루프에 대한 필요가 없습니다

    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
    {
        bulkCopy.DestinationTableName = 
            "dbo.BulkCopyDemoMatchingColumns";
    
        try
        {
            // Write from the source to the destination.
            bulkCopy.WriteToServer(ExitingSqlTableName);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    
  4. ==============================

    4.DataTable을의 직선 경로에서 조금 벗어날 수 있다면 -> SQL 테이블, 그것은 또한 객체의 목록을 통해 수행 할 수 있습니다 :

    DataTable을의 직선 경로에서 조금 벗어날 수 있다면 -> SQL 테이블, 그것은 또한 객체의 목록을 통해 수행 할 수 있습니다 :

    1) DataTable에 - 객체> 일반 목록

    public static DataTable ConvertTo<T>(IList<T> list)
    {
        DataTable table = CreateTable<T>();
        Type entityType = typeof(T);
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
    
        foreach (T item in list)
        {
            DataRow row = table.NewRow();
    
            foreach (PropertyDescriptor prop in properties)
            {
                row[prop.Name] = prop.GetValue(item);
            }
    
            table.Rows.Add(row);
        }
    
        return table;
    }
    

    소스 및 자세한 내용은 여기에서 찾을 수 있습니다. 누락 된 속성을 기본값으로 유지됩니다 (int 치의 0 등 참조 유형의 널 (null))

    2) 데이터베이스에 개체를 밀어

    한 가지 방법은 EntityFramework.BulkInsert 확장자를 사용하는 것입니다. EF의 데이터 컨텍스트는하지만, 필요합니다.

    그것은 빠른 인서트 (사용자 정의 테이블 형식 용액이보다 훨씬 느리다)에 필요한 대량 INSERT 명령을 생성한다.

    하지 직선 방법이지만, 훨씬 더 많은 메모리를 효율적으로 보인다 대신 DataTables의 객체 목록 작업의 기반을 구축하는 데 도움이됩니다.

  5. ==============================

    5.나는 사용자 정의 데이터 형식을 선호 : 그것은 매우 빠릅니다.

    나는 사용자 정의 데이터 형식을 선호 : 그것은 매우 빠릅니다.

    CREATE TYPE [dbo].[udtProduct] AS TABLE(
      [ProductID] [int] NULL,
      [ProductName] [varchar](50) NULL,
      [ProductCode] [varchar](10) NULL
    )
    GO
    
    CREATE PROCEDURE ProductBulkInsertion 
    @product udtProduct readonly
    AS
    BEGIN
        INSERT INTO Product
        (ProductID,ProductName,ProductCode)
        SELECT ProductID,ProductName,ProductCode
        FROM @product
    END
    
    SqlCommand sqlcmd = new SqlCommand("ProductBulkInsertion", sqlcon);
    sqlcmd.CommandType = CommandType.StoredProcedure;
    sqlcmd.Parameters.AddWithValue("@product", productTable);
    sqlcmd.ExecuteNonQuery();
    

    가능한 문제 : 알터 사용자 정의 테이블

    실제로 ALTER 사용자 정의 형식에는 SQL 서버의 명령이 없습니다 그러나 관리 스튜디오에서 당신은 다음 단계에서이를 얻을 수 있습니다

    유형에 대한 1.generate 스크립트. (파일 새 쿼리 창에서 또는) 2.delete 사용자가 테이블을 뒤엎었다. (가) 스크립트를 생성하고 실행 3.modify.

  6. ==============================

    6.당신은 테이블 값 매개 변수를 사용하여이 작업을 수행 할 수 있습니다.

    당신은 테이블 값 매개 변수를 사용하여이 작업을 수행 할 수 있습니다.

    다음 문서에서보세요 :

    http://www.codeproject.com/Articles/39161/C-and-Table-Value-Parameters

  7. from https://stackoverflow.com/questions/10405373/insert-entire-datatable-into-database-at-once-instead-of-row-by-row by cc-by-sa and MIT license