diff --git a/SqlBulkTools.IntegrationTests/App.config b/SqlBulkTools.IntegrationTests/App.config
index 029df70..86b4cd1 100644
--- a/SqlBulkTools.IntegrationTests/App.config
+++ b/SqlBulkTools.IntegrationTests/App.config
@@ -4,8 +4,9 @@
-
-
+
+
+
diff --git a/SqlBulkTools.IntegrationTests/Model/Book.cs b/SqlBulkTools.IntegrationTests/Model/Book.cs
index b8f95b1..c97b798 100644
--- a/SqlBulkTools.IntegrationTests/Model/Book.cs
+++ b/SqlBulkTools.IntegrationTests/Model/Book.cs
@@ -26,6 +26,8 @@ public class Book
[Required]
[Index]
public decimal? Price { get; set; }
+
+ public float? TestFloat { get; set; }
}
}
diff --git a/SqlBulkTools.IntegrationTests/Scripts/TestDataTypesTable.sql b/SqlBulkTools.IntegrationTests/Scripts/TestDataTypesTable.sql
new file mode 100644
index 0000000..10245b9
--- /dev/null
+++ b/SqlBulkTools.IntegrationTests/Scripts/TestDataTypesTable.sql
@@ -0,0 +1,21 @@
+CREATE TABLE [dbo].[TestDataTypes]
+(
+FloatTest float(24),
+FloatTest2 float,
+DecimalTest decimal(14,2),
+MoneyTest money,
+SmallMoneyTest smallmoney,
+NumericTest numeric(30,2),
+RealTest real,
+DateTimeTest datetime,
+DateTime2Test datetime2,
+SmallDateTimeTest smalldatetime,
+DateTest date,
+TimeTest time,
+GuidTest uniqueidentifier,
+TextTest text,
+VarBinaryTest varbinary(20),
+BinaryTest binary(10),
+TinyIntTest tinyint,
+BigIntTest bigint
+);
\ No newline at end of file
diff --git a/SqlBulkTools.IntegrationTests/SqlBulkToolsIT.cs b/SqlBulkTools.IntegrationTests/SqlBulkToolsIT.cs
index 6d635e1..1c2b32a 100644
--- a/SqlBulkTools.IntegrationTests/SqlBulkToolsIT.cs
+++ b/SqlBulkTools.IntegrationTests/SqlBulkToolsIT.cs
@@ -607,6 +607,54 @@ public void SqlBulkTools_WhenUsingReservedSqlKeywords()
}
+ [Test]
+ public void SqlBulkTools_BulkInsertOrUpdate_DecimalValueCorrectlySet()
+ {
+
+ _db.Books.RemoveRange(_db.Books.ToList());
+ _db.SaveChanges();
+
+ decimal? expectedPrice = (decimal?)1.33;
+
+ BulkOperations bulk = new BulkOperations();
+ List books = new List() { new Book() { Description = "Test", ISBN = "12345678910", Price = expectedPrice } };
+
+ bulk.Setup(x => x.ForCollection(books))
+ .WithTable("Books")
+ .AddAllColumns()
+ .BulkInsertOrUpdate()
+ .MatchTargetOn(x => x.ISBN)
+ .SetIdentityColumn(x => x.Id);
+
+ bulk.CommitTransaction("SqlBulkToolsTest");
+
+ Assert.AreEqual(_db.Books.First().Price, expectedPrice);
+
+ }
+
+ [Test]
+ public void SqlBulkTools_BulkInsertOrUpdae_FloatValueCorrectlySet()
+ {
+ _db.Books.RemoveRange(_db.Books.ToList());
+ _db.SaveChanges();
+
+ float? expectedFloat = (float?)1.33;
+
+ BulkOperations bulk = new BulkOperations();
+ List books = new List() { new Book() { Description = "Test", ISBN = "12345678910", Price = 30, TestFloat = expectedFloat} };
+
+ bulk.Setup(x => x.ForCollection(books))
+ .WithTable("Books")
+ .AddAllColumns()
+ .BulkInsertOrUpdate()
+ .MatchTargetOn(x => x.ISBN)
+ .SetIdentityColumn(x => x.Id);
+
+ bulk.CommitTransaction("SqlBulkToolsTest");
+
+ Assert.AreEqual(_db.Books.First().TestFloat, expectedFloat);
+ }
+
private void AppendToLogFile(string text)
{
diff --git a/SqlBulkTools/BulkOperationsHelpers.cs b/SqlBulkTools/BulkOperationsHelpers.cs
index d03e6ed..2c4f494 100644
--- a/SqlBulkTools/BulkOperationsHelpers.cs
+++ b/SqlBulkTools/BulkOperationsHelpers.cs
@@ -17,22 +17,49 @@ namespace SqlBulkTools
{
internal class BulkOperationsHelpers
{
+ internal struct PrecisionType
+ {
+ public string NumericPrecision { get; set; }
+ public string NumericScale { get; set; }
+ }
+
internal string BuildCreateTempTable(HashSet columns, DataTable schema, bool? outputIdentity = null)
{
Dictionary actualColumns = new Dictionary();
Dictionary actualColumnsMaxCharLength = new Dictionary();
+ Dictionary actualColumnsPrecision = new Dictionary();
foreach (DataRow row in schema.Rows)
{
+ string columnType = row["DATA_TYPE"].ToString();
+ string columnName = row["COLUMN_NAME"].ToString();
+
actualColumns.Add(row["COLUMN_NAME"].ToString(), row["DATA_TYPE"].ToString());
- actualColumnsMaxCharLength.Add(row["COLUMN_NAME"].ToString(),
- row["CHARACTER_MAXIMUM_LENGTH"].ToString());
+
+ if (columnType == "varchar" || columnType == "nvarchar" ||
+ columnType == "char" || columnType == "binary" ||
+ columnType == "varbinary")
+
+ {
+ actualColumnsMaxCharLength.Add(row["COLUMN_NAME"].ToString(),
+ row["CHARACTER_MAXIMUM_LENGTH"].ToString());
+ }
+
+ if (columnType == "numeric" || columnType == "decimal")
+ {
+ PrecisionType p = new PrecisionType
+ {
+ NumericPrecision = row["NUMERIC_PRECISION"].ToString(),
+ NumericScale = row["NUMERIC_SCALE"].ToString()
+ };
+ actualColumnsPrecision.Add(columnName, p);
+ }
+
}
StringBuilder command = new StringBuilder();
-
command.Append("CREATE TABLE #TmpTable(");
List paramList = new List();
@@ -44,17 +71,8 @@ internal string BuildCreateTempTable(HashSet columns, DataTable schema,
string columnType;
if (actualColumns.TryGetValue(column, out columnType))
{
- if (columnType == "varchar" || columnType == "nvarchar")
- {
- string maxCharLength;
- if (actualColumnsMaxCharLength.TryGetValue(column, out maxCharLength))
- {
- if (maxCharLength == "-1")
- maxCharLength = "max";
-
- columnType = columnType + "(" + maxCharLength + ")";
- }
- }
+ columnType = GetVariableCharType(column, columnType, actualColumnsMaxCharLength);
+ columnType = GetDecimalPrecisionAndScaleType(column, columnType, actualColumnsPrecision);
}
paramList.Add("[" + column + "]" + " " + columnType);
@@ -73,6 +91,38 @@ internal string BuildCreateTempTable(HashSet columns, DataTable schema,
return command.ToString();
}
+ private string GetVariableCharType(string column, string columnType, Dictionary actualColumnsMaxCharLength)
+ {
+ if (columnType == "varchar" || columnType == "nvarchar")
+ {
+ string maxCharLength;
+ if (actualColumnsMaxCharLength.TryGetValue(column, out maxCharLength))
+ {
+ if (maxCharLength == "-1")
+ maxCharLength = "max";
+
+ columnType = columnType + "(" + maxCharLength + ")";
+ }
+ }
+
+ return columnType;
+ }
+
+ private string GetDecimalPrecisionAndScaleType(string column, string columnType, Dictionary actualColumnsPrecision)
+ {
+ if (columnType == "decimal" || columnType == "numeric")
+ {
+ PrecisionType p;
+
+ if (actualColumnsPrecision.TryGetValue(column, out p))
+ {
+ columnType = columnType + "(" + p.NumericPrecision + ", " + p.NumericScale + ")";
+ }
+ }
+
+ return columnType;
+ }
+
internal string BuildJoinConditionsForUpdateOrInsert(string[] updateOn, string sourceAlias, string targetAlias)
{
StringBuilder command = new StringBuilder();