如何将地理批量插入新的 sql server 2008 表
Posted
技术标签:
【中文标题】如何将地理批量插入新的 sql server 2008 表【英文标题】:How to bulk insert geography into a new sql server 2008 table 【发布时间】:2011-08-23 18:01:40 【问题描述】:我有一个非常大的形状文件,其中包含数十万行多边形和其他相关数据,例如格式化的地址和 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();
但这只能让我单独导入多边形——我还需要其他所有东西。
【问题讨论】:
csv 文件根本不起作用,因为 ssis 不会接受 WFT 或 WFD 作为批量插入的有效字段。我唯一的希望是创建一个像这里看到的二进制数据文件(***.com/questions/282604/…),如果我只想导入地理,上面的代码效果很好。问题是我有更多的信息可以进入文件,而不仅仅是地理信息,我不知道如何构建我的二进制文件或我的格式文件,所以我可以做一个正确的 bcp 或 openrowset。 对于未来的读者来说,值得知道的是.NET中的SqlBulkCopy可以直接插入SqlGeography类型。在此处查看此 SO 答案:***.com/a/21128445 【参考方案1】:好吧,经过几天的头痛,我得出了没有答案的结论。甚至强大的 ESRI 也没有任何线索。谢天谢地,我确实想出了一个不同的灵魂。在我的表定义中,我创建了一个 NVARCHAR(MAX) 列来保存我的地理位置的 WFT 并将该 WFT 添加到我的 csv 文件中,然后在批量插入之后我运行一个表范围的更新语句以将 WFT 转换为实际的地理类型.还要调整 csv 文件以使用除 a 之外的其他字符,以分隔,因为 WFT 包含 ,'s
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);
【讨论】:
以上是关于如何将地理批量插入新的 sql server 2008 表的主要内容,如果未能解决你的问题,请参考以下文章
使用 pymssql 将文本文件批量插入 SQL Server
尝试将数据表批量插入 SQL Server 时出现 InvalidOperationException
如何使用SQL Server中的DataTable模拟“批量”插入