我正在尝试解决使邮政编码正确显示的一些困难。
原始电子表格包含 5 位和 9 位混合格式的邮政编码。在导入过程之后,这些 9 位邮政编码报告的长度为 12 位。现在,当我尝试在 9 位邮政编码中添加连字符“-”时,由于长度错误和各种数据类型转换问题,我得到了异常结果和错误。
使用用于从电子表格导入数据的 openrowset 方法执行导入。
当我查询新导入的数据时,我看到邮政编码显示与电子表格中的相同,但长度错误。
SELECT ZIP,
LEN(LTRIM(RTRIM(Zip))) AS ZIPLENGTH
FROM XLS_IMPORT
ZIP ZIPLENGTH
45750 5
432013256 12
441153221 12
44120 5
441351362 12
如果我选择数据的左 9 个字符,所有内容都会转换为浮点数,并且邮政编码现在不可读。
SELECT LEFT(ZIP,9) FROM XLS_IMPORT
WHERE LEN(LTRIM(RTRIM(ZIP))) = 12
ZIP
4.32013e+
4.42034e+
4.56637e+
4.41153e+
4.36045e+
4.41133e+
如何将这些邮政编码恢复为正确的 9 位数字?或者如何在报告长度为 12 的 9 位邮政编码中添加连字符?我的最终目标是简单地让 9 位邮政编码在中间有一个连字符。
该Zip
列的数据类型是float
.
我刚刚发现我的一些电子表格(例如 NJ 和 NY)在邮政编码的前导 0 之前有一个撇号。我将需要研究如何处理 '0xxxx 邮政编码以使其适用于我的一些电子表格导入。
邮政编码是字符串,而不是数字。其中一些有 1 个甚至 2 个(但不超过 2 个)前导零。导入表中的数据类型应
VARCHAR(10)
使其可以容纳 5 位和 9 位 + 连字符邮政编码。即使您永远不必存储其他国家/地区的邮政编码,即使这些值只有数字(即 0 - 9),该数据仍然是字符串数据,就像电话号码一样。根据您的其他问题中显示的导入查询(自动导入和导出进程 EXCEL -> SQL SERVER -> EXCEL without using SSIS):
我建议不要依赖
SELECT INTO
构造来创建XLS_IMPORT
表,而是手动创建导入表,然后使用INSERT INTO ... SELECT FROM OPENROWSET()
构造。这样做可以让您做以下事情来改善这种情况:ZipCode
字段为VARCHAR(10)
FLOAT
值432013256
,将返回432013256
而不是4.32013e+008
(这是转换为 时得到的VARCHAR
)。使用以下内容修复任何丢失的前导零:
例子:
回报:
理想情况下,您会将电子表格中的列定义固定为字符串。但即使您这样做,保留此代码可能仍然是一个好主意。
考虑到这一目标,以下内联 TVF 可用于将
FLOAT
值转换为VARCHAR
,并为 ZIP + 4 值添加连字符。iTVF 代码:
测试:
回报:
为了更清楚地了解建议的内容,以下显示了上面提到的所有建议:
一些电子表格“知道”有前导零,因此在 Excel 中的字段前加上一个撇号,以便 Excel 将值视为字符串而不是数字(例如
'01234
)。在这种情况下,您可以使用该REPLACE
函数删除该撇号。但是,您不能
REPLACE
在所有电子表格上使用,因为将ZIP
列作为数字的电子表格在CONVERT_IMPLICIT
将值传递给REPLACE
函数时会执行 a 并且转换后的值将采用科学计数法(例如1.23457e+008
)。因此,如果您不能确定 将返回哪种数据类型OPENROWSET
,那么您可以使用IIF
(或者CASE
如果使用 2012 年之前的 SQL Server 版本)并CHARINDEX
测试是否存在撇号。如果数据以 形式返回,那么在将值传递到时将发生FLOAT
隐式转换,因为其中没有撇号,并且转换后的值只会到而不是到。VARCHAR
CHARINDEX
1.23457e+008
CHARINDEX
dbo.FormatZIPCode
显然,此时您已经意识到邮政编码应该存储为字符串而不是数字。如果没有其他原因,只是外国(非美国)邮政编码经常包含字母。
也就是说,让我们回到你原来的问题。为什么当你有 5 个数字时你的长度显示为 5,而当你只存储 9 个数字时你的长度显示为 12。这与LEN 函数的工作方式有关。如果您查看此示例代码的 XML 执行计划:
你会注意到这两行:
您是否看到
CONVERT_IMPLICIT
在varchar(23)
获取LEN
. (据我所知LEN
,实际上只适用于字符串。)因此,让我们看一下
CONVERT_IMPLICIT
通过显式转换实际返回的内容。现在我们看到它
12345
转换得很干净。123456789
但是需要科学记数法。给我们1.23457e+008
。长度为 12 个字符。邮政编码作为浮点数据类型导入。我无法将列直接从 float 转换为 varchar(10)。相反,我将数据类型从浮点数转换为十进制,然后从十进制转换为 varchar(10)。现在,该列正在报告正确的邮政编码位数 (9)。现在允许在 9 位邮政编码中插入连字符。