开篇介绍
这是今天在帮别人看一个 2008R2 版本的项目时发现的一个 Bug,这个 Bug 在 SQL SERVER 2012 有的版本中可能已经解决,但在论坛上看到有的仍然存在。
在 SQL SERVER 2008 R2 版本中,比如从一个数据库表中取一个 BIGINT 类型的数据,赋值给一个 Int64 类型的变量,按照我们的理解肯定是正确的。
但是结果是报错了 -
错误原因
类型不一致造成的 ——
[Execute SQL Task] Error: An error occurred while assigning a value to variable "MAX_ID": "The type of the value being assigned to variable "User::MAX_ID" differs from the current variable type. Variables may not change type during execution. Variable types are strict, except for variables of type Object.".
当时也非常的奇怪,觉得这里的配置没有任何问题,怀疑同事机器环境有问题,于是就在我本机 SQL SERVER 2012 的环境下测试了一遍。
同样的逻辑是通过的。
后来到网上查了一下,果然是 SQL SERVER 2008 R2 版本中的一个 BUG,始自 2005,很惭愧,我到现在才发现这是一个 BUG。
http://blogs.msdn.com/b/mattm/archive/2007/04/18/why-can-t-i-store-my-bigint-result-in-an-int64-variable.aspx
Why can’t I store my BIGINT result in an Int64 variable?
The native providers (OLEDB, ODBC, ADO – ADO.NET doesn't have this problem) in the Execute SQL Task return the BIGINT type as a String, and not an Int64 as you'd expect. Attempting to store the result in an Int64 variable gives you an error along the lines of:
[Execute SQL Task] Error: An error occurred while assigning a value to variable "xxxx": "The type of the value being assigned to variable "xxxx" differs from the current variable type. Variables may not change type during execution. Variable types are strict, except for variables of type Object."
Although this behavior is documented in the books online entry, we don't explain why it was done this way. Being somewhat new to the SSIS development team, I had to do some digging to find out for myself. It turns out that at the time this was implemented, there wasn't cross platform support for the 8-byte integer type (VT_I8/VT_UI8) in VARIANTs -- specifically, on Windows 2000. Now that supporting Win2k is no longer an issue (for Katmai), we're free to change the behavior (while maintaining backwards compatibility for packages that are expecting the value as a string, of course).
Expect this as a likely change in an upcoming release.
https://connect.microsoft.com/SQLServer/feedback/details/260967/ssis-sql-server-bigint-doesnt-map-to-int64
解决方式
SQL SERVER 2012 版本已经纠正过来了,所以用 SQL SERVER 2012 的时候应该没有问题。如果还是使用 SQL SERVER 2008 R2 的话,解决的办法就是将数据类型改为 String,用它来接受 SQL SERVER 中 BIGINT 数据类型的数据。
另外,可能大家会问 - 如何这个变量正好也要写入一个 COLUMN类型为 BIGINT 类型的数据表中怎么办?
这个是没有任何问题的,如果 COLUMN 的类型是数值,日期的话,String 类型会自动发生转换插入的,因此 String 的变量会自动转换为对应的 BIGINT 插入到数据表中。