【发布时间】:2020-09-05 03:41:01
【问题描述】:
我有许多包含 200 多列的非规范化表。这些表位于 SQL Server 中,并且它们通常(如果不总是)具有 varchar(100) 或 nvarchar(100)(字符串)数据类型。但是,大多数列是整数、浮点数或其他数据类型。我不可能遍历每个表和列并挑选数据类型。由于许多原因,包括应用程序兼容性、性能、加入和其他原因,我必须将这些转换为正确的(或至少接近正确的)数据类型。有什么我可以使用的工具吗?有没有人创建代码来完成这个?它不一定是完美的,但接近匹配就可以了。
我尝试了什么:
- 我尝试将这些表导出到 Excel,然后返回 SQL。它起作用了,但是比手动操作要花费更多的时间,因为 Excel 会破坏您的数据并将其转换为任何感觉(想想科学记数法、数字日期等……天哪!)。这非常耗时并且失败了。如果您选择在 Excel 中使用“文本”选项,它只会将所有内容转换回 varchar (x)
- 我尝试导出到平面文件并使用具有智能数据类型的 VS 或 SSMS 新版本。这比 Excel 效果更好,但不幸的是,即使是单行冲突也会停止整个过程。该工具很笨重,会出现严重错误,并且不会告诉您是哪一行导致了问题。使用这种方法也很糟糕,因为这些表很大,而且非常耗时。尤其是在考虑工具故障排除时。
感谢您的帮助。如果您不要求我通过尝试说我的设置不好/等等来放弃任务,我也很感激。
【问题讨论】:
-
您能否澄清一下,当您说“正确”数据类型时,“正确”是什么意思?
-
@Nabav 我认为这很清楚,但我会更明确。如果 A 列的值介于 1-20 之间,理想情况下它应该是一个小的 int 或 int。具有 2.4 的 colB 应该是浮点数,而不是 varchar(100)。我明白你不可能有完美的结果。我也了解潜在的危险,例如带有前导 0 的邮政编码会丢失,但至少拥有合理正确的数据类型是一个好的开始。
-
我做了something like this for integer-based data。但是,如果您的起始列是一个字符串,我想您将从任何一个即使单个值是
ISNUMERIC() = 0的列开始,您也可以消除转换为数字类型的可能性,并且任何具有一个ISDATE() = 0的值,您从日期/时间候选人中删除。如果您有所有数据为 ISNUMERIC 的列,那么您可以开始测试它们的长度(最大长度、小数点后的最大长度等)。 -
@AaronBertrand 谢谢!您的文章对整数非常有价值,可惜它不适用于字符串!实际上,我认为使用 ISNUMERIC/ISDATE 确实是我应该使用的。我知道这些功能,但不知何故,在想到这个可怕的任务时从未想到过!再次感谢
-
我在写答案时没有想到这一点,但我突然想到
TRY_CONVERT()可能是一种更精确的方法来确定一个值是否应该是某种类型,而不是依靠 ISNUMERIC/ISDATE 的牛仔滑稽动作(它们不是超级可靠的)。CASE WHEN TRY_CONVERT(tinyint, col) IS NULL THEN 'will not fit in tintint' WHEN TRY_CONVERT(int, col) IS NULL THEN 'will not fit in int' etc. etc.
标签: sql sql-server ssis sql-server-data-tools sql-server-2019