Я работаю с 2 серверами SQL 2008 на разных машинах. Имена серверов: source.ex.com
и destination.ex.com
.SqlBulkInsert с DataTable на связанный сервер
destination.ex.com
связан с source.ex.com
и соответствующими разрешениями на месте для source.ex.com
записи в базу данных под названием bacon-wrench
на destination.ex.com
Я вошедший в source.ex.com
с помощью SMS и тестировал этот запрос (успешно):
INSERT INTO [destination.ex.com].[bacon-wrench].[dbo].[tblFruitPunch]
(PunchID, BaconID) VALUES (4,6);
в C# .NET 4.0 WebPage я подключиться к source.ex.com
и выполнить аналогичный запрос (успешно):
using(SqlConnection c = new SqlConnection(ConfigurationManager.ConnectionStrings["SOURCE"].ConnectionString))
{
c.Open();
String sql = @"
INSERT INTO [destination.ex.com].[bacon-wrench].[dbo].[tblFruitPunch]
(PunchID, BaconID) VALUES (34,56);";
using(SqlCommand cmd = new SqlCommand(sql, c))
{
cmd.ExecuteNonQuery();
}
}
Для небольших наборов утверждений вставки (скажем, 20 или меньше) делает что-то вроде этого выполняет отлично:
using(SqlConnection c = new SqlConnection(ConfigurationManager.ConnectionStrings["SOURCE"].ConnectionString))
{
c.Open();
String sql = @"
INSERT INTO [destination.ex.com].[bacon-wrench].[dbo].[tblFruitPunch]
(PunchID, BaconID) VALUES (34,56);
INSERT INTO [destination.ex.com].[bacon-wrench].[dbo].[tblFruitPunch]
(PunchID, BaconID) VALUES (22,11);
INSERT INTO [destination.ex.com].[bacon-wrench].[dbo].[tblFruitPunch]
(PunchID, BaconID) VALUES (33,55);
INSERT INTO [destination.ex.com].[bacon-wrench].[dbo].[tblFruitPunch]
(PunchID, BaconID) VALUES (1,2);";
using(SqlCommand cmd = new SqlCommand(sql, c))
{
cmd.ExecuteNonQuery();
}
}
Я пытаюсь сделать что-то вроде этого с около 20000 записей. Вышеуказанный метод занимает 11 минут, чтобы завершить, что, я полагаю, является сервером, который навязывает мне, чтобы сделать его какой-то объемной операцией. Из других потоков StackOverflow был рекомендован класс SqlBulkCopy
, и он принимает в качестве параметра DataTable
, отлично!
Так что я построить DataTable и попытаться записать его на сервер (обязательно):
DataTable dt = new DataTable();
dt.Columns.Add("PunchID", typeof(int));
dt.Columns.Add("BaconID", typeof(int));
for(int i = 0; i < 20000; i++)
{
//I realize this would make 20000 duplicate
//rows but its not important
dt.Rows.Add(new object[] {
11, 33
});
}
using(SqlConnection c = new SqlConnection(ConfigurationManager.ConnectionStrings["SOURCE"].ConnectionString))
{
c.Open();
using(SqlBulkCopy bulk = new SqlBulkCopy(c))
{
bulk.DestinationTableName = "[destination.ex.com].[bacon-wrench].[dbo].[tblFruitPunch]";
bulk.ColumnMappings.Add("PunchID", "PunchID");
bulk.ColumnMappings.Add("BaconID", "BaconID");
bulk.WriteToServer(dt);
}
}
edit2: Ниже сообщение, что я пытаюсь исправить:
веб-страница аварий на bulk.WriteToServer(dt);
с сообщением об ошибке Database bacon-wrench does not exist please ensure it is typed correctly.
Что я делаю неправильно? Как изменить это, чтобы заставить его работать?
EDIT1:
Я был в состоянии ускорить запрос значительно ниже, используя синтаксис. Но для такого небольшого набора записей он все еще очень медленный.
using(SqlConnection c = new SqlConnection(ConfigurationManager.ConnectionStrings["SOURCE"].ConnectionString))
{
c.Open();
String sql = @"
INSERT INTO [destination.ex.com].[bacon-wrench].[dbo].[tblFruitPunch]
(PunchID, BaconID) VALUES
(34,56),
(22,11),
(33,55),
(1,2);";
using(SqlCommand cmd = new SqlCommand(sql, c))
{
cmd.ExecuteNonQuery();
}
}
Oh Noes! Я попробую, как вы предложили. –