【发布时间】:2021-01-01 13:36:36
【问题描述】:
我正在运行控制台应用程序并使用 SqlBulkCopy 将记录从 .NET DataTable 写入 MSSQL 数据库。
.NET 中有一列:new DataColumn(columnName, typeof(decimal));,其中一行的值为:384.50000。
运行 SqlBulkCopy 时(在具有较小值的批次上运行良好)我收到以下错误:
System.InvalidOperationException: The given value of type SqlDecimal from the data source cannot be converted to type decimal of the specified target column. ---> System.InvalidOperationException: The given value of type SqlDecimal from the data source cannot be converted to type decimal of the specified target column. ---> System.ArgumentException: Parameter value '384.50000' is out of range.
--- End of inner exception stack trace ---
at System.Data.SqlClient.SqlBulkCopy.ConvertValue(Object value, _SqlMetaData metadata, Boolean isNull, Boolean& isSqlType, Boolean& coercedToDataFeed)
--- End of inner exception stack trace ---
at System.Data.SqlClient.SqlBulkCopy.ConvertValue(Object value, _SqlMetaData metadata, Boolean isNull, Boolean& isSqlType, Boolean& coercedToDataFeed)
at System.Data.SqlClient.SqlBulkCopy.ReadWriteColumnValueAsync(Int32 col)
at System.Data.SqlClient.SqlBulkCopy.CopyColumnsAsync(Int32 col, TaskCompletionSource`1 source)
at System.Data.SqlClient.SqlBulkCopy.CopyRowsAsync(Int32 rowsSoFar, Int32 totalRows, CancellationToken cts, TaskCompletionSource`1 source)
at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsync(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet internalResults, CancellationToken cts, TaskCompletionSource`1 source)
at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletionSource`1 source)
at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalAsync(CancellationToken ctoken)
at System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServerAsync(Int32 columnCount, CancellationToken ctoken)
at System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable table, DataRowState rowState)
at System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable table)
目标数据库表中的列如下:
,[Test_Column] DECIMAL(38,5) NULL
decimal[ (p[ ,s] )] p(精度)要存储的十进制数字的最大总数。这个数字包括小数点的左边和右边。精度必须是从 1 到最大精度 38 之间的一个值。
鉴于这种情况,我不明白为什么会出现错误:
The given value of type SqlDecimal from the data source cannot be converted to type decimal of the specified target column. ---> System.ArgumentException: Parameter value '384.50000' is out of range.
谁能解释一下如何解决这个问题?
我已尝试将 db 类型更改为 float 以查看是否可行,但是当我将来自 csv 的值转换为 .NET DataTable 时,我无法放弃指数表示法。当它是十进制时,这有效:
Decimal.Parse("-5E-05", NumberStyles.Float); -0.00005 decimal
但是当它是浮动时,这不起作用:
(float)Decimal.Parse(text, NumberStyles.Float); -5E-05 float
另外值得一提的是,我有在 SqlBulkCopy 中添加列映射的代码。 CSV、.NET DataTable 和 DB 表都是从我在 .NET 中使用的相同类型定义创建的。例如;在 SQL 中它是 Decimal(38,5) 它是 .NET DataTable 中的小数,并且列名在 CSV、.NET Datatabe 和 DB 表中都匹配。
环境:
MSSQL Server 2019 开发者版
视窗 10
C# 控制台应用程序 .NET 4.7.2
视觉工作室 2019
【问题讨论】:
-
将DataTable列的类型设置为SqlDecimal,并用
new SqlDecimal(val)加载每个值
标签: sql-server tsql sqlbulkcopy sql-server-2019