Ошибка ввода данных с использованием 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()
}
}
Итак, я получаю сообщение об ошибке:
Данное значение типа SqlDateTime
из источника данных не может быть преобразовано в тип date
указанного целевого столбца.
Почему?? Как я могу это исправить? Помогите мне, пожалуйста!
Ответы
Ответ 1
Используя исходную таблицу script, работает следующий код.
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.
Ответ 2
Тип SQL Date отличается от типа SQL DateTime. Я думаю, что столбец даты в вашей таблице должен иметь тип DateTime, основанный на том, как вы его используете.
Тип даты SQL
SQL DateTime type
Update:
Я думаю, что ответ Marc должен работать, но вам, вероятно, нужно указать SqlBulkCopyColumnMappings из вашего исходного DataTable в пункт назначения, иначе это может привести к неправильному отображению, потому что структура вашей входной таблицы не соответствует выходной таблице точно, то есть порядок столбцов даты и строки.
например,
var amount = new SqlBulkCopyColumnMapping("amount", "amount");
var date = new SqlBulkCopyColumnMapping("date", "date");
bulk.ColumnMappings.Add(amount);
bulk.ColumnMappings.Add(date);
Ответ 3
SqlDateTime
представляет собой оригинальный тип datetime
. Пробовали ли вы просто использовать тип datetime
.NET в DataTable
? Я надеюсь, что он может преобразовать это в типы TSQL datetime
или date
. Тоже decimal
вместо SqlDecimal
.