从只有 nvarchar 字段的表中推断出数据类型?

问题描述

我有一张这样的桌子:

Create table landingzone.classes(
teacher nvarchar(255),moment nvarchar(255),noOfStudents nvarchar(255),scheduledYesNo nvarchar(255)
)

INSERT INTO [landingzone].[classes]
           ([teacher],[moment],[noOfStudents],[scheduledYesNo]) 
Select ' Henrov','  01/07/2021',6,'True' 
union all 
Select ' Bill','  01/05/2021','False' 
union all
Select ' Henrov','  31/07/2021',NULL,NULL

我需要的是一个脚本来发现

  • [teacher] 应该是 nvarchar(255)
  • [moment] 应该是 timestamp
  • [noOfStudents] 应该是 int
  • [ScheduledYesNo] 应为 bit(或值为 1/0 的 int

并创建一个这样的表:

Create table staging.classes(
teacher nvarchar(255),moment datetime,noOfStudents int,scheduledYesNo bit
)

接着是从 landingzone.classesstaging.classes 的数据传输。

然而,它应该通过分析表 dbo.test 来实现这一点,而不是通过引用一些包含具有关联数据类型的列的名称的配置表来实现。由于 dbo.test 中可能有大量记录,其中许多字段可能为空,因此应该查看前 200 条(最好这个数字应该是可配置的)

landingzone 中的表由其他流程提供,并且应明确地以当前表单(业务规则)存在。

我认为最大的挑战在于自动发现正确的数据类型。

这可以在 BIML 中完成吗?

解决方法

没有 Biml 方法可以帮助您检测数据类型。

我参与了一个从大型机中提取无类型数据的长期项目,我们对您正在做的事情采取了类似的方法。我们将数据按原样放入具有该系统允许的最宽字符串类型的表中*

我们编写了一个 TSQL 脚本,它可以对表进行逆透视,然后生成 N 列对数据进行分析。一系列测试看起来像(徒手编码,所以要遵循精神而不是字母):

SELECT
  MIN(LEN([teacher])),MAX(LEN([teacher])),COUNT_BIG(DISTINCT([teacher])),COUNT_BIG(WHEN NULLIF(LTRIM(RTRIM([teacher],''))) IS NOT NULL THEN 1 END AS NotNullOrEmpty,''))) IS NULL THEN 1 END AS NullOrEmpty,COUNT_BIG(CASE WHEN TRY_CONVERT('bigint',[teacher]) IS NULL THEN 1 END) AS NotBigInt,[teacher]) IS NOT NULL THEN 1 END) AS BigInt

这样做的目的是生成关于列外观的描述性统计信息 - 填充的频率、适合各种数据类型的百分比、最小/最大长度

我们遇到的问题。

无数据或数据稀疏。这很容易成为我们屁股上最大的一口。如果我没记错的话,NULL 会很高兴地转换为整数类型,所以一旦我们有足够的数据,我们就有很多事情要做。为自己省点心,如果您没有太多数据,请将其保留为字符串 ;)

本地数据规则。我们遇到了罐头脚本无法处理的事情。大型机使用插入符号 ^ 表示时间结束

日期和时间。 Model204 可以处理 3 月 32 日。显然这与 4 月 1 日相同,对吗?与 3 月 31 日 24:30 相同,显然是 4 月 1 日 00:30

*“哦,是的,我们确实有这些字段,我们可以在其中存储二进制/超长字符串。我们没有告诉过你吗?”