我使用BIML构建多个SSIS包,我必须在日期间隔之间从OLE DB源检索数据。这是要生成包的xml:
<Dataflow Name="DFT Insert into <#=TableName#>">
<Transformations>
<OleDbSource Name="Retreive from Source (<#=TableName#>)" ConnectionName="AS400">
<DirectInput>
SELECT s.*
FROM <#=TableSchema#>.<#=TableName#> s
WHERE s.date > ? AND s.date <= ?
</DirectInput>
<Parameters>
<Parameter Name="0" VariableName="User.StartDate"/>
<Parameter Name="1" VariableName="User.MiddleDate"/>
</Parameters>
</OleDbSource>
<OleDbDestination Name="Insert into Destination (<#=TableName#>)" ConnectionName="DB2Mirror" KeepNulls="true" CheckConstraints="false">
<ExternalTableOutput Table="[<#=TableSchema#>].[<#=TableName#>]" />
</OleDbDestination>
</Transformations>
</Dataflow>
这种结构通常可以正常工作,因为我已经尝试了但是用ID(int)而不是日期(字符串)。我在尝试生成程序包时收到的错误如下:
Could not execute Query on Connection AS400
OleDbCommand.Prepare method requires all variable length parameters to have an explicitly set non-zero Size.
我知道我可以创建一个ssis变量并将查询中的日期作为表达式连接起来,但我想坚持使用<DirectInput>
而不是<VariableInput>
其他信息
日期时间(对不起,我忘了提到它是日期时间,但我认为它没有太大变化)变量中的格式是正确的:yyyy-mm-dd hh:mm:ss。我非常确定格式没有任何问题,因为我试图创建一个变量作为表达式,连接这样的日期:<Variable Name="Query" DataType="String" EvaluateAsExpression="true">"SELECT * FROM table WHERE col > '" + @[User::StartDate] + "'"</Variable>
并且它有效。有一件事我忘了提及它可能很重要的是源dbms是db2
答案 0 :(得分:3)
给出以下表格定义
CREATE TABLE dbo.so_42623962
(
RowSk int NOT NULL
, [Date] date
);
这是我使用OLE DB Sources参数的最小可行Biml
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Connections>
<OleDbConnection Name="tempdb" ConnectionString="Data Source=localhost\dev2016;Initial Catalog=tempdb;Provider=SQLNCLI11.0;Integrated Security=SSPI;"/>
</Connections>
<Packages>
<Package Name="so_42623962" >
<Variables>
<Variable Name="StartDate" DataType="String">2017-01-01</Variable>
<Variable Name="MiddleDate" DataType="String">2017-01-01</Variable>
</Variables>
<Tasks>
<Dataflow Name="DFT Demo">
<Transformations>
<OleDbSource Name="SRC Query" ConnectionName="tempdb">
<DirectInput><![CDATA[SELECT *
FROM dbo.so_42623962 AS X
WHERE X.[Date] > ? AND X.[Date] <= ? ;]]></DirectInput>
<Parameters>
<Parameter Name="0" VariableName="User.StartDate" />
<Parameter Name="1" VariableName="User.MiddleDate" />
</Parameters>
</OleDbSource>
<DerivedColumns Name="DER Placeholder" />
</Transformations>
</Dataflow>
</Tasks>
</Package>
</Packages>
</Biml>
那将构建一个包很好。如果我取出CDATA,它需要放弃大于/小于字符,它仍然有效
<Dataflow Name="DFT Escaped">
<Transformations>
<OleDbSource Name="SRC Query" ConnectionName="tempdb">
<DirectInput>SELECT *
FROM dbo.so_42623962 AS X
WHERE X.[Date] > ? AND X.[Date] <= ?;</DirectInput>
<Parameters>
<Parameter Name="0" VariableName="User.StartDate" />
<Parameter Name="1" VariableName="User.MiddleDate" />
</Parameters>
</OleDbSource>
<DerivedColumns Name="DER Placeholder" />
</Transformations>
</Dataflow>
如果我没有用括号括起Date
列,那么仍然
<Dataflow Name="DFT Escapedx2">
<Transformations>
<OleDbSource Name="SRC Query" ConnectionName="tempdb">
<DirectInput>SELECT *
FROM dbo.so_42623962 AS X
WHERE X.Date > ? AND X.Date <= ?;</DirectInput>
<Parameters>
<Parameter Name="0" VariableName="User.StartDate" />
<Parameter Name="1" VariableName="User.MiddleDate" />
</Parameters>
</OleDbSource>
<DerivedColumns Name="DER Placeholder" />
</Transformations>
</Dataflow>
那么我的工作演示和你的演示之间还剩下什么?更容易解决的是日期的价值(开始/中间日期)。我使用yyyy-mm-dd aka ccyy-mm-dd往往被我使用的系统更普遍地理解,但你可能会尝试yyyymmdd的ISO标准。
更难处理的事情是您的连接管理器名为AS400。事实上,因为我不得不处理他们使用的Julian dates的另一个问题上的“奇怪”日期,但是我看到AS400使用的CYMD格式同样是“奇怪的”并且你是必须使用派生列编写自己的表达式,将yyyy-mm-dd日期转换为CYMD。不应该很难,但考虑到可能的日期格式的丰富性,我不会冒险猜测。