Как массово вставить географию в новую таблицу sql server 2008

У меня есть очень большой файл формы с сотнями тысяч строк полигонов и другими связанными данными, такими как форматированная адресация и номера APN. Как мне получить эти данные в таблицу с географией без использования таких вещей, как Shape2SQL? Я не могу запустить оператор вставки для каждой строки, что заняло бы вечность, оптимальным решением было бы создать csv или правильно отформатированный файл bin, а затем выполнить массовую вставку, или bcp, или openrowset, но попробуйте, попробуйте , как бы я ни старался, я не могу заставить работать CSV-файл или bin-файл. Кто-нибудь может помочь?

Следующий код - лучшее, что я мог сделать.

SqlGeographyBuilder sql_geography_builder = new SqlGeographyBuilder();
sql_geography_builder.SetSrid(4326);
sql_geography_builder.BeginGeography(OpenGisGeographyType.Polygon);
sql_geography_builder.BeginFigure(-84.576064, 39.414853);
sql_geography_builder.AddLine(-84.576496, 39.414800);
sql_geography_builder.AddLine(-84.576522, 39.414932);
sql_geography_builder.AddLine(-84.576528, 39.414964);
sql_geography_builder.AddLine(-84.576095, 39.415015);
sql_geography_builder.AddLine(-84.576064, 39.414853);
sql_geography_builder.EndFigure();
sql_geography_builder.EndGeography();
SqlGeography sql_geography = new SqlGeography();
sql_geography = sql_geography_builder.ConstructedGeography;


FileStream file_stream = new FileStream("C:\\PROJECTS\\test.bin", FileMode.Create);
BinaryWriter binary_writer = new BinaryWriter(file_stream);

sql_geography.Write(binary_writer);
binary_writer.Flush();

binary_writer.Close();
file_stream.Close();
file_stream.Dispose();

SqlConnection sql_connection = new SqlConnection(connection_string);
sql_connection.Open();

SqlCommand sql_command = new SqlCommand();
sql_command.Connection = sql_connection;
sql_command.CommandTimeout = 0;
sql_command.CommandType = CommandType.Text;
sql_command.CommandText = "INSERT INTO [SPATIAL_TEST].[dbo].[Table_1] ([geo]) " +
              "SELECT [ors].* " +
              "FROM OPENROWSET(BULK 'C:\\PROJECTS\\AMP\\test.bin', SINGLE_BLOB) AS [ors] ";
sql_command.ExecuteNonQuery();

sql_command.Dispose();
sql_connection.Close();
sql_connection.Dispose();

Но это позволяет мне импортировать только один многоугольник — мне нужно и все остальное.


person Mike Underwood    schedule 23.08.2011    source источник
comment
csv просто не работают, так как ssis не будет принимать WFT или WFD в качестве допустимого поля для массовой вставки. Моя единственная надежда состояла в том, чтобы создать файл двоичных данных, как показано здесь (stackoverflow.com/questions/282604/), и приведенный выше код отлично работает, если все, что я хочу сделать, это просто импортировать только географию. Проблема в том, что у меня гораздо больше информации для ввода в файл, чем просто география, и я не могу понять, как создать свой двоичный файл или файл формата, чтобы я мог сделать правильный bcp или openrowset.   -  person Mike Underwood    schedule 23.08.2011
comment
Будущим читателям стоит знать, что SqlBulkCopy в .NET может напрямую вставлять типы SqlGeoegraphy. См. этот ответ SO здесь: stackoverflow.com/a/21128445   -  person Mark Glasgow    schedule 31.08.2017


Ответы (1)


Ну после нескольких дней головной боли я пришел к выводу, что ответа нет. Даже могущественный ESRI не имеет ни малейшего представления об этом. К счастью, я придумал другую душу. В своем определении таблицы я создал столбец NVARCHAR(MAX) для хранения WFT моей географии и добавил этот WFT в свой CSV-файл, а затем после массовой вставки я запускаю статус обновления таблицы, чтобы преобразовать WFT в фактический тип географии. . Также настройте файл csv, чтобы использовать другой символ, кроме a, чтобы разделить его, потому что WFT содержит,

SqlGeographyBuilder sql_geography_builder = new SqlGeographyBuilder();
sql_geography_builder.SetSrid(4326);
sql_geography_builder.BeginGeography(OpenGisGeographyType.Polygon);
sql_geography_builder.BeginFigure(-84.576064, 39.414853);
sql_geography_builder.AddLine(-84.576496, 39.414800);
sql_geography_builder.AddLine(-84.576522, 39.414932);
sql_geography_builder.AddLine(-84.576528, 39.414964);
sql_geography_builder.AddLine(-84.576095, 39.415015);
sql_geography_builder.AddLine(-84.576064, 39.414853);
sql_geography_builder.EndFigure();
sql_geography_builder.EndGeography();
SqlGeography sql_geography = new SqlGeography();
sql_geography = sql_geography_builder.ConstructedGeography;

StreamWriter stream_writer = new StreamWriter("C:\\PROJECTS\\AMP\\test.csv");
stream_writer.AutoFlush = true;
stream_writer.WriteLine("1?123 TEST AVE?" + sql_geography.ToString() + "?");
stream_writer.Flush();
stream_writer.WriteLine("2?456 TEST AVE?" + sql_geography.ToString() + "?");
stream_writer.Flush();
stream_writer.WriteLine("9?789 TEST AVE?" + sql_geography.ToString() + "?");
stream_writer.Flush();
stream_writer.Close();
stream_writer.Dispose();

SqlConnection sql_connection = new SqlConnection(STRING_SQL_CONNECTION);
sql_connection.Open();

SqlCommand sql_command = new SqlCommand();
sql_command.Connection = sql_connection;
sql_command.CommandTimeout = 0;
sql_command.CommandType = CommandType.Text;
sql_command.CommandText = "BULK INSERT [SPATIAL_TEST].[dbo].[Table_1] " +
                          "FROM 'C:\\PROJECTS\\AMP\\test.csv' " +
                          "WITH (FIELDTERMINATOR = '?', ROWTERMINATOR = '\n') " +
                          "" +
                          "UPDATE [SPATIAL_TEST].[dbo].[Table_1] " +
                          "SET [geo] = geography::STPolyFromText([geo_string], 4326) ";
sql_command.ExecuteNonQuery();

sql_command.Dispose();
sql_connection.Close();
sql_connection.Dispose();

MessageBox.Show("DONE");
}
catch (Exception ex)
{ MessageBox.Show(ex.Message); }
person Mike Underwood    schedule 25.08.2011