报告的错误表明故障点是平面文件源
[平面文件源 [85]] 错误:数据转换失败。 “纬度”列的数据转换返回状态值 2 和状态文本“由于可能丢失数据,无法转换该值。”。
我使用的是美国语言环境机器,因此您可能遇到小数分隔符问题。如果是这种情况,那么在您的平面文件源中,右键单击并选择显示高级编辑器。转到输入和输出属性,然后在平面文件源输出下,展开输出列,对于每个浮点数列,检查FastParse 选项。
如果可行,那太好了,您有一个有效的平面文件源。
我能够以两种不同的方式实现这一点。我在我的包中定义了两个平面文件连接管理器:FFCM Dec 和 FFCM String 虽然我更喜欢尽量减少我应用到我的包的操作和转换的数量,但将数据类型声明为字符串可以帮助您克服“由于数据不正确,我什至无法启动数据流”
源数据
我创建了一个保存为 UTF-8 的 CSV
Latitude,Longitude
41.896585191199556,-87.66454238198166
FFCM 十二月
我配置了一个标准的 CSV
我用DT_DECIMAL 的DataType 定义了我的列
FFCM 字符串
首页相同,但在高级部分的列中,我将数据类型保留为 DT_WSTR,长度为 50
至此,我们已经定义了源数据结构的基本属性。
目的地
我对目的地的尺寸保持一致。使用 10 与 11 不会节省任何东西,而且我懒得查找允许的经纬度数域
CREATE TABLE dbo.SO_65909630
(
[Latitude] decimal(18,15)
, [Longitude] decimal(18,15)
)
数据流
我需要运行,但您要么在输入时使用正确键入的数据 (DFT DEC),要么转换它。
我在您的源数据中看到的空白可能需要处理(您有需要转义的列或没有数据 - 这将导致数据转换失败,所以我提倡这种方法
行计数只是为了在我构建答案时提供一个放置数据查看器的地方
我应该为 lat 和 long 使用什么数据类型
Decimal 是一种精确的数据类型,因此它将存储您提供的 exact 值。使用时采用decimal(scale, precision) 的形式。在担任当前职位之前,我从未使用过任何其他数据类型来表示非整数。
十进制和数字在线书籍 (Transact-SQL) https://docs.microsoft.com/en-us/sql/t-sql/data-types/decimal-and-numeric-transact-sql?view=sql-server-ver15
规模
要存储的十进制数字的最大总数。这个数字包括小数点的左边和右边。精度必须是从 1 到最大精度 38 之间的值。默认精度是 18。
精度
小数点右侧存储的小数位数。从 p 中减去该数字以确定小数点左侧的最大位数。 Scale 必须是从 0 到 p 的值,并且只能在指定精度的情况下指定。默认比例为 0,因此 0
Precision Storage bytes
1 - 9 5
10-19 9
20-28 13
29-38 17
对于我在上面定义的表格,存储每个 lat/long 将花费我们 18 个字节 (2 * 9)。
但是让我们看看实际的纬度和经度域(在地球上) 这个关于 GIS.se 的精彩答案被打印出来并挂在我的工作监视器 https://gis.stackexchange.com/questions/8650/measuring-accuracy-of-latitude-and-longitude
在此处粘贴相关位
-
小数点后六位的值最高为 0.11 m:您可以使用它来详细布置结构、设计景观、修建道路。它应该足以跟踪冰川和河流的运动。这可以通过对 GPS 采取艰苦的措施来实现,例如差分校正 GPS。
-
小数点后七位最高可达 11 毫米:这对于大量测量来说是有利的,并且接近基于 GPS 的技术所能达到的极限。
-
小数点后八位 最高可达 1.1 毫米:这对于绘制构造板块运动和火山运动的图表非常有用。永久性、经过校正、持续运行的 GPS 基站或许能够达到这种准确度。
-
小数点后第九位的值高达 110 微米:我们正在进入显微镜的范围。对于几乎所有可以想到的具有地球位置的应用,这都是多余的,而且比任何测量设备的精度都要精确。
-
十位或更多小数表示使用了计算机或计算器,并且没有注意额外的小数是无用的事实。请小心,因为除非您是从设备上读取这些数字的人,否则这可能表明处理质量低下!
您的输入值显示超过 10 位的精度,所以我猜这是一个计算值,而不是“真正的观察”。这很好,这给了我们更多的工作空间。
为什么,我们可以将下面的十进制声明调低一半*第一个的存储成本
CREATE TABLE dbo.SO_65909630_alt
(
[Latitude] decimal(8,5)
, [Longitude] decimal(8,5)
);
这很好,我们以更低的成本存储了“相同”的数据。也许您的用例只是“我的商店在哪里”,即使您是拥有不到 12000 家商店的沃尔玛,谁在乎呢?这是微不足道的成本。但是,如果您还需要存储他们客户的坐标,那么每条记录的存储成本可能就很重要了。或者在您阅读本文时使用亚马逊或阿里巴巴或任何存在的非常大的消费者零售商。
在我的工作中,我处理气象数据,它有各种形状和大小,但对我来说,一个常见的来源是Stage IV data它只是美国毗连的每小时降雨量。因此,每天每个坐标有 24 个读数。坐标系为 1121 x 881(987,601 点),因此表示美国一天的每小时降雨量为 23,702,424 行。鉴于 Stage IV 数据可追溯到 2008 年,因此 18 字节与 10 字节之间的差异很快就会变得明显。
我们实际上使用float(或实数)来存储纬度和经度值,因为它为每个坐标节省了 2 个字节。
CREATE TABLE dbo.SO_65909630_float
(
[Latitude] float(24)
, [Longitude] float(24)
);
INSERT INTO dbo.SO_65909630_alt
(
Latitude
, Longitude
)
SELECT * FROM dbo.SO_65909630 AS S
现在,这让我很痛苦,因为浮点数很有趣,我无法在查询中使用精确过滤器。
我的十进制类型表中有这个
41.89659 -87.66454
我的浮动类型表里面有这个
41.89658 -87.66454
您是否注意到纬度中最后一位数字的变化? 8 不是 9,因为十进制表有,但无论哪种方式,都没有关系
SELECT * FROM dbo.SO_65909630_float AS S WHERE S.Latitude = 41.89658
由于浮点舍入完全匹配废话,这不会找到一行。相反,您的查询变成了范围很窄的查询,例如
SELECT * FROM dbo.SO_65909630_float AS S WHERE S.Latitude >= (41.89658 - .00005) AND S.Latitude <= (41.89658 + .00005)
.00005 是一个值,您必须根据您的数据进行试验,以确定您需要调整多少数字才能再次找到它。
最后,不管怎样,如果您将 lat 和 long 转换为 Geography Point,它将强制输入数据类型按原样浮动。