平面文件目标列数据类型验证

时间:2019-03-01 19:56:26

标签: csv ssis integer flat-file ssis-data-types

通过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]范围之外。

作为一个相关问题,是否可以将二进制数据输出到平面文件?如果是这样,应该使用什么设置以及在哪里使用?

2 个答案:

答案 0 :(得分:2)

数据类型验证

我认为此问题与所使用的连接管理器有关,因为数据类型验证(管道外部)不是由Integration Services完成的,而是由服务提供者完成的:

  • 用于Excel和Access的OLEDB
  • 用于SQL Server的SQL数据库引擎
  • ...

对于平面文件连接管理器,它不保证任何数据类型的一致性,因为所有值均存储为文本。作为示例,尝试添加一个平面文件连接管理器并选择一个包含名称的文本文件,尝试将column数据类型更改为Date并转到Columns预览选项卡,它将显示所有列而没有任何问题。它仅照顾用于从平面文件读取的行分隔符,列分隔符,文本限定符和公共属性。 (类似于VB.NET中的TextFieldParser类)

数据类型可能会导致异常的唯一情况是,当您使用平面文件源时,因为平面文件源将在平面文件连接管理器和链接中使用定义的元数据创建一个外部列将它们复制到原始列(当您打开平面文件源的高级编辑器时),当SSIS尝试从平面文件源读取时,外部列将引发异常

二进制输出

您应在包内将列转换为二进制并将其映射到目标列。例如,您可以使用脚本组件执行此操作:

public override void myInput_ProcessInputRow(myInputBuffer Row)
  {

  Row.ByteValues=System.Text.Encoding.UTF8.GetBytes (Row.name);

  }

我没有尝试过将其与Derived列或Data conversion转换一起使用。

参考

答案 1 :(得分:0)

重新阅读问题以确保它与我的证明编辑匹配后,我意识到似乎没有我回答您的问题-对此感到抱歉。如果有帮助,我会留下第一个答案。

SSIS似乎没有强制执行目标元数据;但是,它将强制执行源元数据。我创建了一个范围为-127到400的测试文件。我在以下情况下进行了测试:

  • 测试1:具有签名1字节数据类型的源和目标平面文件连接管理器。
  • 结果1:失败
  • 测试2:源为4字节带符号,目标为1字节带符号。
  • 结果2:通过

SSIS的管道元数据验证仅关心匹配管道宽度的输入的元数据。似乎不在乎输出是什么。不过,它使您能够将目标设置为任何下游源,以便它可以检查并提供警告(如果目标的(即SQL Server)元数据是否匹配。

这是一个意外的结果-我希望它会像您一样失败。从直觉上讲,它没有失败的事实仍然是有道理的。由于我们正在写入CSV文件,因此无法控制所需的元数据。但是,如果我们将其连接到SQL Server目标并且元数据不匹配,则SQL Server将对超出范围的数据不满意(请参阅我的其他答案)。

现在,我仍然将输出的元数据设置为匹配管道中的内容,因为在区分字符串数据类型与数字数据类型时,这具有重要的考虑因素。因此,如果您尝试将日期时间设置为整数,则将没有文本限定符,这可能会导致下一个输入过程出错。相反,您可能会遇到同样的问题,即为varchar设置一个整数并拥有一个,这意味着它将获得一个文本限定符。

我认为未强制执行目标元数据这一事实在SSIS中有点薄弱环节。但是,可以通过将其设置为与管道缓冲区匹配来否定否定条件,前提是假定它是最后一项落在设计中的任务,则自动完成此操作。话虽这么说,如果在开发完成后更新管道上的元数据,那么您真正需要在整个管道中更新元数据,因为某些任务必须打开和关闭,而其他任务则必须删除和删除。重新创建以更新元数据。

其他信息

TL DR: TinyInt作为无符号数据类型存储在SQL Server中,这意味着它支持0到255之间的值。因此,可以接受大于127的值-最多255。将导致错误。

字节大小表示可能的组合的最大数目,其中有符号/无符号表示范围是否在正值和负值之间划分。

  • 1个字节= SQL Server中的TinyInt
  • 1个字节是8位= 256个组合
  • 签名范围:-128至127
  • 无符号范围:0到255

请务必注意,SQL Server 不支持直接对数据类型进行签名。我的意思是没有办法将整数数据类型(即TinyInt,Int和BigInt)设置为有符号或无符号。

  • TinyInt是未签名
  • Int和BigInt被签名

请参阅下面的参考: SQL Server自动身份字段的最大大小

如果我们尝试将TinyInt设置为无符号范围之外的任何值(例如-1或256),则会收到以下错误消息:

TinyInt Error Message

这就是为什么您可以设置大于127的值的原因。

内部错误消息:

Int Error Message

BigInt错误消息:

BigInt Error Message

对于Identity列,如果我们将Identity列声明为Int(即32位〜= 43亿个组合)并将种子设置为0(增量为1),则SQL Server将仅转到2,147,483,647行之前它停止,这是最大有符号值。但是,我们的范围缩短了一半。如果将种子设置为-2,147,483,648(不要忘记在范围中包括0),则SQL Server将在停止之前在整个组合范围内递增。

参考:

SSIS Data Types and Limitations

Max Size of SQL Server Auto-Identity Field