Reputation: 1628
I just found out that when you use DataTable
and SqlBulkCopy
in an attempt to load a SQL Server table, you can't use big decimal values.
DataTable
only supports the .NET decimal
type. .NET decimal
is smaller than SQL Server decimal
, so when you exceed the .NET range, you get an exception.
I prepared a DataTable
that contains data rows with SqlDecimal
columns and tried to bulk-load it.
bulkCopy.WriteToServer(dt);
But I get this error:
InvalidCastException: Failed to convert parameter value from a SqlDecimal to a Decimal.
Is there a workaround for this problem?
Update: After David's answer I double-checked the error. It turns out that it is not decimal
but smallmoney
column that caused this issue. An attempt to put SqlDecimal into smallmoney
raises an error. It is very easy to avoid, for smallmoney
and money
columns .NET decimal
is big enough.
Upvotes: 1
Views: 265
Reputation: 89361
I can't repro that.
using System.Data.SqlClient;
using System.Collections;
using System.Data;
using System.Data.Common;
using System.Data.SqlTypes;
using var con = new SqlConnection("server=localhost;database=tempdb;integrated security=true;TrustServerCertificate=true");
con.Open();
var cmd = con.CreateCommand();
cmd.CommandText = "drop table if exists foo; create table foo(id int, d decimal(38,2))";
cmd.ExecuteNonQuery();
var dt = new DataTable();
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("d", typeof(SqlDecimal));
var d = SqlDecimal.Parse("123456789012345678901234567890123456.78");
dt.Rows.Add(1, d);
var bc = new SqlBulkCopy(con);
bc.DestinationTableName = "foo";
bc.WriteToServer(dt);
Upvotes: 0