2009-06-21 9 views
15

SqlBulkCopy을 사용하여 SQL 2008에 데이터를 일괄 적으로 삽입하려고합니다. 내 코드는SqlBulkCopy를 사용하여 데이터를 삽입하는 중 오류가 발생했습니다.

여기
IF OBJECT_ID(N'statement', N'U') IS NOT NULL 
DROP TABLE [statement] 
GO 
CREATE TABLE [statement](
    [ID] INT IDENTITY(1, 1) NOT NULL, 
    [date] DATE NOT NULL DEFAULT GETDATE(), 
    [amount] DECIMAL(14,2) NOT NULL, 
CONSTRAINT [PK_statement] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

입니다 :

private DataTable GetTable() 
{ 
    var list = new List<DataColumn>(); 
    list.Add(new DataColumn("amount", typeof(SqlDecimal))); 
    list.Add(new DataColumn("date", typeof(SqlDateTime))); 

    var table = new DataTable("statement"); 
    table.Columns.AddRange(list.ToArray()); 

    var row = table.NewRow(); 
    row["amount"] = (SqlDecimal)myObj.Amount; // decimal Amount { get; set; } 
    row["date"] = (SqlDateTime)myObj.Date; // DateTime Date { get; set } 
    table.Rows.Add(row); 

    return table; 
} 

private void WriteData() 
{ 
    using (var bulk = new SqlBulkCopy(strConnection, SqlBulkCopyOptions.KeepIdentity & SqlBulkCopyOptions.KeepNulls)) 
    { 
     //table.Columns.ForEach(c => bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping(c.ColumnName, c.ColumnName))); 
     bulk.BatchSize = 25; 
     bulk.DestinationTableName = "statement"; 
     bulk.WriteToServer(GetTable()); // a table from GetTable() 
    } 
} 

그래서 내가지고있어 오류 : 여기

내 테이블

The given value of type SqlDateTime from the data source cannot be converted to type date of the specified target column.

왜? 어떻게 해결할 수 있습니까? 도와주세요, 제발!

답변

19

원본 테이블 스크립트를 사용하면 다음 코드가 작동합니다.

private static DataTable GetTable() 
{ 
    var list = new List<DataColumn>(); 
    list.Add(new DataColumn("amount", typeof(Double))); 
    list.Add(new DataColumn("date", typeof(DateTime))); 
    var table = new DataTable("statement"); 
    table.Columns.AddRange(list.ToArray()); 

    var row = table.NewRow(); 
    row["amount"] = 1.2d; 
    row["date"] = DateTime.Now.Date; 

    table.Rows.Add(row); 
    return table; 
} 
private static void WriteData() 
{ 
    string strConnection = "Server=(local);Database=ScratchDb;Trusted_Connection=True;"; 
    using (var bulk = new SqlBulkCopy(strConnection, SqlBulkCopyOptions.KeepIdentity & SqlBulkCopyOptions.KeepNulls)) 
    { 
     bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping("amount", "amount")); 
     bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping("date", "date")); 
     bulk.BatchSize = 25; 
     bulk.DestinationTableName = "statement"; 
     bulk.WriteToServer(GetTable()); 
    } 
} 

Amal이 이미 설명한 것처럼 Identity 열 때문에 열 매핑이 필요합니다.

+5

"SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.KeepNulls"가 아니어야합니까? – rusty

6

SQL 날짜 유형은 SQL DateTime 유형과 다릅니다. 나는 당신의 테이블에있는 날짜 열이 당신이 그것을 사용하는 방식에 따라 DateTime 타입이어야한다고 생각한다.

SQL Date Type
SQL DateTime type

업데이트 :

나는 마크의 대답은 일을해야한다고 생각하지만, 당신은 아마 그렇지 않으면 매핑 잘못을 받고 수 있습니다, 목적지까지의 소스의 DataTable에서 SqlBulkCopyColumnMappings를 지정해야 입력 테이블의 구조가 출력 테이블과 정확하게 일치하지 않기 때문에 날짜와 행 열의 순서가 바뀌었기 때문입니다.

var amount = new SqlBulkCopyColumnMapping("amount", "amount"); 
var date = new SqlBulkCopyColumnMapping("date", "date"); 
bulk.ColumnMappings.Add(amount); 
bulk.ColumnMappings.Add(date); 
+0

네, 다른 점은 알고 있습니다. 그러나 DbType.DateTime/SqlDateTime/DateTime 만 사방에 있다면 정확히 어떻게 DbType.Date를 사용할 수 있습니까?! – abatishchev

+0

대량로드에 사용하는 임시 테이블에서보다 널리 사용되는 "DATETIME"을 사용하고 "실제"데이터 테이블에서 실제 "DATE"를 사용할 수 있습니다. T-SQL 문에서 날짜에 DateTime을 쉽게 할당 할 수 있습니다. –

2

SqlDateTime 원래 datetime 유형을 나타낸다. DataTableDateTime .NET 유형을 사용하려고 했습니까? TSQL datetime 또는 date 유형으로 변환 할 수 있기를 바랍니다. Dotto decimal 대신 SqlDecimal.

+0

typeof (Double)보다 오류가 발생하는 경우 : "데이터 소스의 SqlString 유형에 지정된 값을 지정된 대상 열의 10 진수로 변환 할 수 없습니다". typeof (DateTime)과 같은 오류! 그리고 적절한 열이 돈을 표현하고 2 자리 숫자가 필요하기 때문에 typeof (10 진수)를 사용할 수 없습니다. – abatishchev

관련 문제