开篇介绍
在 SQL Server 2012 之前的版本中,在包启动之后,如果我们想改变一个变量的值的话,我们是需要通过 Script Task 去完成赋值,或者使用 Execute SQL Task 的 Output 或者 ReturnValue 方式给一个变量来赋值。
但是现在在 SQL Server 2012 版本中我们现在直接有了一个新的控件 Expression Task,我们直接可以通过 Expression Task 来完成对包变量的赋值操作。
阶段一 包运行之前变量的赋值
假设我们定义了一个包变量表示一个输出文件的完全路径,PV_FILE_PATH 的 Value 默认是 D:\BIWORKSPACE_FILE\TS_BIWORK_SSIS\OUTPUT_DIRECTORY\015\2014_09_11_BIWORK.csv
由于我们希望这个文件每天在输出的时候,它文件路径中的日期部分能跟着改编成当前天的时间 - D:\BIWORKSPACE_FILE\TS_BIWORK_SSIS\OUTPUT_DIRECTORY\015\2014_09_21_BIWORK.csv。
那么这样就需要对这个变量的一个属性就行修改,EvaluateAsExpression 属性要设置为 True 并为这个变量提供表达式。(实际上也可以不用设置 EvaluateAsExpression,因为只要给 Expression 表达式设置了,它的这个属性会自行提示修改)。
可以在属性中修改这 EvaluateAsExpression 为 True,然后点击下面的 Expression,或者就上图中的 Expression 后点击也一样可以。
利用表达式来修改变量的值,这样在包运行的时候变量的值就由这个表达式自动计算得来。输入下面的表达式,点击 Evaluate Expression 查看。
"D:\\BIWORKSPACE_FILE\\TS_BIWORK_SSIS\\OUTPUT_DIRECTORY\\015\\"
+ REPLACE( (DT_WSTR, 30)(DT_DBDATE)GETDATE() ,"-","_") + "_BIWORK.csv"
有三点要注意:
- 文件路径中的单斜杠在表达式中要写成双斜杠
- 这个变量是字符串类型,因此表达式中整个计算结果必须是字符串类型,用双引号括起来。
- GETDATE() 获取日期,转换成时间类型之后再变为字符串,最后由 Replace 完成日期中 2014-09-21 到 2014_09_21 的转变。
阶段二 Task 返回值的赋值
有很多时候我们在处理一些时间数据的时候,比如运行期间获得一个日期 2014-09-21,我们需要将这个时间输出到某一个文件。在输出到文件的同时,可能有这样的需求:需要同时获取这个时间对应的月份,例如英文时间序列 Jan, Feb, Mar, Apr, May 或者需要获取这个时间对应的星期几,例如 Sunday, Monday, Tuesday 等等。这个时候就可以利用 Expression Task 给某一个变量赋值,变量拿到值之后就可以用在其它的 Task 中了。
新添加三个变量- PV_DATE,PV_MONTH_NAME 和 PV_DAY_NAME,第一个是时间类型,后面两个是字符串类型。
我们假设在包中有很多的 Task,其中有一个 Execute SQL Task 返回了一个时间,这个时间可能是通过某查询返回的,我们需要先将这个时间赋值给 PV_DATE。
SELECT GETDATE() AS XXXDATE
Result Set 中取返回的第一列的值赋值给变量 PV_DATE。
阶段三 包运行中通过 Expression Task 为变量赋值
拖放两个 Expression Task 控件,并放到 Sequence Container 中。
双击编辑 ET_GET_DAY_NAME,并使用用户自定义变量。
Expression 中的内容为:
@[User::PV_DAY_NAME]=
DATEPART("dw",@[User::PV_DATE] )== 1 ? "Sunday":
DATEPART("dw",@[User::PV_DATE] )== 2 ? "Monday":
DATEPART("dw",@[User::PV_DATE] )== 3 ? "Tuesday":
DATEPART("dw",@[User::PV_DATE] )== 4 ? "Wednesday":
DATEPART("dw",@[User::PV_DATE] )== 5 ? "Thursday":
DATEPART("dw",@[User::PV_DATE]) == 6 ? "Friday":
DATEPART("dw",@[User::PV_DATE]) == 7 ? "Saturday":""
一个 Expression Task 中只配置一个变量,编辑 ET_GET_MONTH_NAME Task。
@[User::PV_MONTH_NAME]=
MONTH(@[User::PV_DATE]) == 1 ? "Jan" :
MONTH(@[User::PV_DATE]) == 2 ? "Feb" :
MONTH(@[User::PV_DATE]) == 3 ? "Mar" :
MONTH(@[User::PV_DATE]) == 4 ? "Apr" :
MONTH(@[User::PV_DATE]) == 5 ? "May" :
MONTH(@[User::PV_DATE]) == 6 ? "Jun" :
MONTH(@[User::PV_DATE]) == 7 ? "Jul" :
MONTH(@[User::PV_DATE]) == 8 ? "Aug" :
MONTH(@[User::PV_DATE]) == 9 ? "Sep" :
MONTH(@[User::PV_DATE]) == 10 ? "Oct" :
MONTH(@[User::PV_DATE]) == 11 ? "Nov" :
MONTH(@[User::PV_DATE]) == 12 ? "Dec":""
添加一个 Script Task 来展示一下这几个变量的值。
代码如下-
public void Main()
{
// TODO: Add your code here
//User::PV_DATE,User::PV_DAY_NAME,User::PV_FILE_PATH,User::PV_MONTH_NAME
string filePath = Dts.Variables["User::PV_FILE_PATH"].Value.ToString();
string sqlDate = Dts.Variables["User::PV_DATE"].Value.ToString();
string day = Dts.Variables["User::PV_DAY_NAME"].Value.ToString();
string month = Dts.Variables["User::PV_MONTH_NAME"].Value.ToString();
MessageBox.Show("File Path - "+filePath+"\nSQL Date -"+sqlDate+"\nMonth - "+month+"\nDay - "+day);
Dts.TaskResult = (int)ScriptResults.Success;
}
保存并执行包就可以看到这几个变量的值了,其中:
- File Path - 是包启动就通过表达式赋值的
- Sql Date - 是通过 Execute SQL Task 返回值赋值的
- Day 和 Month - 是通过在包运行期间通过 Executel SQL Task 的动态返回值来完成表达式赋值的。