平面文件目标列数据类型验证
Flat file destination columns data types validation
通过 OLE DB 源读取 INT 类型的源数据库字段。它最终被写入平面文件目标。目标平面文件连接管理器 > 高级页面将其报告为 four-byte signed integer [DT_I4]
。
这种数据类型让我觉得它表示二进制。显然,事实并非如此。我很惊讶它不是更通用的 numeric [DT_NUMERIC]
.
我将此类型设置更改为 single-byte signed integer [DT_I1]
。我预计这会失败,但事实并非如此。该过程产生相同的结果,即使该字段的值始终 > 127。为什么这没有失败?
产生的一些值是
1679576722
1588667638
1588667638
1497758544
1306849450
1215930367
1215930367
1023011178
1932102084
很明显,超出了single-byte signed integer [DT_I1]
的范围。
作为一个相关问题,是否可以将二进制数据输出到平面文件?如果是这样,应该使用什么设置和位置?
在重新阅读问题以确保它与我的校对编辑相匹配后,我意识到我似乎没有回答你的问题 - 对此感到抱歉。我已经留下了第一个答案以防它有帮助。
SSIS 似乎没有强制执行目标元数据;但是,它将强制执行源元数据。我创建了一个范围为 -127 到 400 的测试文件。我在以下场景中对此进行了测试:
- 测试 1: 带符号 1 字节数据类型的源和目标平面文件连接管理器。
- 结果 1:失败
- 测试 2:源是 4 字节有符号的,目标是 1 字节有符号的。
- 结果二:通过
SSIS 的管道元数据验证只关心与管道宽度匹配的输入元数据。它似乎不关心输出是什么。但是,它使您能够将目标设置为任何下游源,以便它可以检查目标(即 SQL 服务器)的元数据是否匹配并发出警告。
这是一个意外的结果 - 我预计它会像您一样失败。直觉上,它没有失败的事实仍然是有道理的。由于我们正在写入 CSV 文件,因此无法控制所需的元数据是什么。但是,如果我们将其连接到 SQL 服务器目标并且元数据不匹配,那么 SQL 服务器将不接受越界数据(请参阅我的其他答案)。
现在,我仍然会设置输出的元数据以匹配它在管道中的内容,因为这对于区分字符串和数字数据类型具有重要的考虑因素。因此,如果您尝试将日期时间设置为整数,那么将没有文本限定符,这可能会导致下一个输入过程出错。相反,您可能会遇到同样的问题,将整数设置为 varchar 并具有,这意味着它将获得文本限定符。
我认为未强制执行目标元数据这一事实在 SSIS 中有点薄弱 link。但是,它可以通过将其设置为与流水线缓冲区相匹配来取消,这是自动完成的,假设它是丢给设计的最后一个任务。话虽如此,如果您在开发完成后更新管道上的元数据,那么您将真正享受在整个管道中更新元数据的乐趣,因为必须打开和关闭某些任务,而必须删除和删除其他任务重新创建以更新元数据。
附加信息
TL DR: TinyInt 在SQL Server 中存储为无符号数据类型,这意味着它支持 0 到 255 之间的值。所以大于 127 的值可接受 - 最多 255。任何超过都会导致错误。
字节大小表示可能组合的最大数量,其中 signed/unsigned 表示范围是否分为正值和负值。
- 1 字节 = SQL 服务器中的 TinyInt
- 1字节为8位=256种组合
- 有符号范围:-128 到 127
- 无符号范围:0 到 255
重要的是要注意 SQL 服务器 不 支持直接签署数据类型。我在这里的意思是,无法将整数数据类型(即 TinyInt、Int 和 BigInt)设置为有符号或无符号。
- TinyInt 是 unsigned
- Int 和 BigInt 有符号
参见下面的参考:SQL 服务器自动识别字段的最大大小
如果我们尝试将 TinyInt 设置为无符号范围之外的任何值(例如 -1 或 256),则会收到以下错误消息:
这就是您能够设置大于 127 的值的原因。
内部错误信息:
BigInt 错误信息:
关于身份列,如果我们将身份列声明为 Int(即 32 位 ~= 43 亿种组合)并将种子设置为 0,增量为 1,则 SQL 服务器将在它停止之前只转到 2,147,483,647 行,这是最大有符号值。但是,我们的范围短了一半。如果我们将种子设置为 -2,147,483,648(不要忘记在范围内包含 0),那么 SQL 服务器将在停止之前递增整个组合范围。
参考文献:
SSIS Data Types and Limitations
Max Size of SQL Server Auto-Identity Field
数据类型验证
我认为这个问题与使用的连接管理器有关,因为数据类型验证(管道外)不是由集成服务完成的,而是由服务提供商完成的:
- 用于 Excel 和 Access
的 OLEDB
- SQL SQL 服务器的数据库引擎
- ...
当谈到平面文件连接管理器时,它不保证任何数据类型的一致性,因为所有值都是存储为文本。例如,尝试添加一个平面文件连接管理器和 select 一个包含名称的文本文件,尝试将列数据类型更改为日期并转到列预览选项卡,它将毫无问题地显示所有列。它只处理行分隔符、列分隔符、文本限定符和用于从平面文件读取的常用属性。 (类似于VB.NET中的TextFieldParser class)
数据类型可能导致异常的唯一情况是当您使用平面文件源时,因为平面文件源将创建一个外部列,其中定义了平面文件中的元数据文件连接管理器和 link 它们到原始列(你可以看到当你打开平面文件源的高级编辑器时)当 SSIS 尝试从平面文件源读取时 外部列将抛出异常.
二进制输出
您应该在包中将该列转换为二进制文件并将其映射到目标列。例如,您可以使用脚本组件来执行此操作:
public override void myInput_ProcessInputRow(myInputBuffer Row)
{
Row.ByteValues=System.Text.Encoding.UTF8.GetBytes (Row.name);
}
我还没有尝试过这是否适用于派生列或数据转换转换。
参考资料
通过 OLE DB 源读取 INT 类型的源数据库字段。它最终被写入平面文件目标。目标平面文件连接管理器 > 高级页面将其报告为 four-byte signed integer [DT_I4]
。
这种数据类型让我觉得它表示二进制。显然,事实并非如此。我很惊讶它不是更通用的 numeric [DT_NUMERIC]
.
我将此类型设置更改为 single-byte signed integer [DT_I1]
。我预计这会失败,但事实并非如此。该过程产生相同的结果,即使该字段的值始终 > 127。为什么这没有失败?
产生的一些值是
1679576722
1588667638
1588667638
1497758544
1306849450
1215930367
1215930367
1023011178
1932102084
很明显,超出了single-byte signed integer [DT_I1]
的范围。
作为一个相关问题,是否可以将二进制数据输出到平面文件?如果是这样,应该使用什么设置和位置?
在重新阅读问题以确保它与我的校对编辑相匹配后,我意识到我似乎没有回答你的问题 - 对此感到抱歉。我已经留下了第一个答案以防它有帮助。
SSIS 似乎没有强制执行目标元数据;但是,它将强制执行源元数据。我创建了一个范围为 -127 到 400 的测试文件。我在以下场景中对此进行了测试:
- 测试 1: 带符号 1 字节数据类型的源和目标平面文件连接管理器。
- 结果 1:失败
- 测试 2:源是 4 字节有符号的,目标是 1 字节有符号的。
- 结果二:通过
SSIS 的管道元数据验证只关心与管道宽度匹配的输入元数据。它似乎不关心输出是什么。但是,它使您能够将目标设置为任何下游源,以便它可以检查目标(即 SQL 服务器)的元数据是否匹配并发出警告。
这是一个意外的结果 - 我预计它会像您一样失败。直觉上,它没有失败的事实仍然是有道理的。由于我们正在写入 CSV 文件,因此无法控制所需的元数据是什么。但是,如果我们将其连接到 SQL 服务器目标并且元数据不匹配,那么 SQL 服务器将不接受越界数据(请参阅我的其他答案)。
现在,我仍然会设置输出的元数据以匹配它在管道中的内容,因为这对于区分字符串和数字数据类型具有重要的考虑因素。因此,如果您尝试将日期时间设置为整数,那么将没有文本限定符,这可能会导致下一个输入过程出错。相反,您可能会遇到同样的问题,将整数设置为 varchar 并具有,这意味着它将获得文本限定符。
我认为未强制执行目标元数据这一事实在 SSIS 中有点薄弱 link。但是,它可以通过将其设置为与流水线缓冲区相匹配来取消,这是自动完成的,假设它是丢给设计的最后一个任务。话虽如此,如果您在开发完成后更新管道上的元数据,那么您将真正享受在整个管道中更新元数据的乐趣,因为必须打开和关闭某些任务,而必须删除和删除其他任务重新创建以更新元数据。
附加信息
TL DR: TinyInt 在SQL Server 中存储为无符号数据类型,这意味着它支持 0 到 255 之间的值。所以大于 127 的值可接受 - 最多 255。任何超过都会导致错误。
字节大小表示可能组合的最大数量,其中 signed/unsigned 表示范围是否分为正值和负值。
- 1 字节 = SQL 服务器中的 TinyInt
- 1字节为8位=256种组合
- 有符号范围:-128 到 127
- 无符号范围:0 到 255
重要的是要注意 SQL 服务器 不 支持直接签署数据类型。我在这里的意思是,无法将整数数据类型(即 TinyInt、Int 和 BigInt)设置为有符号或无符号。
- TinyInt 是 unsigned
- Int 和 BigInt 有符号
参见下面的参考:SQL 服务器自动识别字段的最大大小
如果我们尝试将 TinyInt 设置为无符号范围之外的任何值(例如 -1 或 256),则会收到以下错误消息:
这就是您能够设置大于 127 的值的原因。
内部错误信息:
BigInt 错误信息:
关于身份列,如果我们将身份列声明为 Int(即 32 位 ~= 43 亿种组合)并将种子设置为 0,增量为 1,则 SQL 服务器将在它停止之前只转到 2,147,483,647 行,这是最大有符号值。但是,我们的范围短了一半。如果我们将种子设置为 -2,147,483,648(不要忘记在范围内包含 0),那么 SQL 服务器将在停止之前递增整个组合范围。
参考文献:
SSIS Data Types and Limitations
Max Size of SQL Server Auto-Identity Field
数据类型验证
我认为这个问题与使用的连接管理器有关,因为数据类型验证(管道外)不是由集成服务完成的,而是由服务提供商完成的:
- 用于 Excel 和 Access 的 OLEDB
- SQL SQL 服务器的数据库引擎
- ...
当谈到平面文件连接管理器时,它不保证任何数据类型的一致性,因为所有值都是存储为文本。例如,尝试添加一个平面文件连接管理器和 select 一个包含名称的文本文件,尝试将列数据类型更改为日期并转到列预览选项卡,它将毫无问题地显示所有列。它只处理行分隔符、列分隔符、文本限定符和用于从平面文件读取的常用属性。 (类似于VB.NET中的TextFieldParser class)
数据类型可能导致异常的唯一情况是当您使用平面文件源时,因为平面文件源将创建一个外部列,其中定义了平面文件中的元数据文件连接管理器和 link 它们到原始列(你可以看到当你打开平面文件源的高级编辑器时)当 SSIS 尝试从平面文件源读取时 外部列将抛出异常.
二进制输出
您应该在包中将该列转换为二进制文件并将其映射到目标列。例如,您可以使用脚本组件来执行此操作:
public override void myInput_ProcessInputRow(myInputBuffer Row)
{
Row.ByteValues=System.Text.Encoding.UTF8.GetBytes (Row.name);
}
我还没有尝试过这是否适用于派生列或数据转换转换。
参考资料