仅使用 nvarchar 字段从 table 推导出数据类型?

Deduce dataypes from table with only nvarchar fields?

我有一个 table 这样的:

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' ,6 ,'False' 
union all
Select ' Henrov', '  31/07/2021' ,NULL ,NULL

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

并像这样创建一个 table:

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

随后是从 landingzone.classesstaging.classes 的数据传输。

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

landingzone 中的 tables 由其他进程交付,应明确保持当前形式(业务规则)的存在。

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

这可以在 BIML 中完成吗?

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

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

我们编写了一个 TSQL 脚本,该脚本将反转 table,然后生成 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
, COUNT_BIG(WHEN NULLIF(LTRIM(RTRIM([teacher], ''))) IS NULL THEN 1 END AS NullOrEmpty
, COUNT_BIG(CASE WHEN TRY_CONVERT('bigint', [teacher]) IS NULL THEN 1 END) AS NotBigInt
, COUNT_BIG(CASE WHEN TRY_CONVERT('bigint', [teacher]) IS NOT NULL THEN 1 END) AS BigInt

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

我们 运行 遇到的问题。

没有数据或数据稀疏。那很容易成为我们背后最大的咬伤。如果我没记错的话,NULL 会很乐意转换为整数类型,所以一旦我们有足够的数据,我们就有很多事后要做的更正。省去一些麻烦,如果您没有太多数据,请将其保留为字符串 ;)

本地数据规则。我们 运行 处理固定脚本无法处理的事情。大型机使用插入符号 ^ 表示时间结束

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

*“哦,是的,我们确实有这些字段可以存储 binary/very 长字符串。我们没有告诉你这些吗?”