我有一个简单的要求。我有一个包含产品名称及其计数的表格。我想创建一个SSIS包,根据产品名称将数据从一个表提取到无限表。 在表格中,如果我有10个产品,那么SSIS包应该动态地创建10个表,每个表中有一个产品。
表名:产品
ProductName , QuantitySold
ABC 10
xyz 15
Testing 25
表名:ABC
ProductName , QuantitySold
ABC 10
表名:XYZ
ProductName , QuantitySold
xyz 15
表名:测试
ProductName , QuantitySold
ABC 10
答案 0 :(得分:2)
从概念上讲,你正在寻找像
这样的东西
概念是您将识别表中的所有产品名称并在每行上执行2个任务:如果需要,创建目标表。针对该行的源运行查询并将其加载到表中。
我声明了6个变量
Query_TableCreateBase是一个格式化为
的大字符串IF NOT EXISTS
(
SELECT
*
FROM
sys.tables AS T
WHERE
T.name = '<Table/>'
)
BEGIN
CREATE TABLE dbo.<Table/>
(
ProductName varchar(30) NOT NULL
, QuantitySold int NOT NULL
);
END
我在Query_Source,Query_TableCreate和TargetTable
上有表达式Query_Source表达式
"SELECT ProductName, QuantitySold FROM (
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold) WHERE ProductName = '" + @[User::ProductName] + "'"
Query_TableCreate表达式
replace(@[User::Query_TableCreateBase], "<Table/>", @[User::ProductName])
TargetTable表达式
"[dbo].[" +@[User::ProductName] + "]"
我使用查询模拟您的Products表。我将这些结果加载到名为RS_Product的变量中。
SELECT
ProductName
FROM
(
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold);
我使用Foreach循环容器,设置为处理ADO结果集并将第0列解析为我们的ProductName变量
这是一个被评估为类似
的查询IF NOT EXISTS
(
SELECT
*
FROM
sys.tables AS T
WHERE
T.name = 'Foo'
)
BEGIN
CREATE TABLE dbo.Foo
(
ProductName varchar(30) NOT NULL
, QuantitySold int NOT NULL
);
END
我将此设置为DelayValidation = true,因为该表可能不会存在,直到它获得启动信号。
再次,模拟您的Products表,我的查询看起来像
SELECT ProductName, QuantitySold FROM (
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold) WHERE ProductName = 'Foo'
严格地说,不需要数据流。如果我们撤回源查询中的所有列,则可以通过您的执行SQL任务完成所有操作。
商业智能标记语言Biml描述了商业智能平台。在这里,我们将使用它来描述ETL。 BIDS Helper,是Visual Studio / BIDS / SSDT的免费补充,它解决了许多缺点。具体来说,我们将使用将描述ETL的Biml文件转换为SSIS包的能力。这样做的另一个好处是为您提供了一种机制,可以准确生成我所描述的解决方案,而不是点击许多繁琐的对话框。
以下代码假定您在本地计算机上有一个默认实例,而在tempdb中,您有一个名为Foo的表。
use tempdb;
GO
CREATE TABLE dbo.Foo
(
ProductName varchar(30) NOT NULL
, QuantitySold int NOT NULL
);
将以下脚本保存到.biml文件中,当您添加到SSIS项目时,该文件将显示在Miscellaneous虚拟文件夹下。右键单击,选择Generate SSIS Package,它应该创建一个名为so_27320726
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Connections>
<OleDbConnection Name="tempdb" ConnectionString="Data Source=localhost;Initial Catalog=tempdb;Provider=SQLNCLI10.1;Integrated Security=SSPI;" />
</Connections>
<Packages>
<Package Name="so_27320726" ConstraintMode="Parallel" >
<Variables>
<Variable Name="ProductName" DataType="String">Foo</Variable>
<Variable Name="Query_Source" DataType="String" EvaluateAsExpression="true">"SELECT ProductName, QuantitySold FROM (
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold) WHERE ProductName = '" + @[User::ProductName] + "'"</Variable>
<Variable Name="Query_TableCreate" DataType="String" EvaluateAsExpression="true"><![CDATA[replace(@[User::Query_TableCreateBase], "<Table/>", @[User::ProductName])]]></Variable>
<Variable Name="Query_TableCreateBase" DataType="String" ><![CDATA[IF NOT EXISTS
(
SELECT
*
FROM
sys.tables AS T
WHERE
T.name = '<Table/>'
)
BEGIN
CREATE TABLE dbo.<Table/>
(
ProductName varchar(30) NOT NULL
, QuantitySold int NOT NULL
);
END]]></Variable>
<Variable Name="RS_Product" DataType="Object" />
<Variable Name="TargetTable" DataType="String" EvaluateAsExpression="true">"[dbo].[" +@[User::ProductName] + "]"</Variable>
</Variables>
<Tasks>
<ExecuteSQL Name="SQL Get Rows" ConnectionName="tempdb" ResultSet="Full">
<Variables>
<Variable Name="Variable" DataType="Int32" IncludeInDebugDump="Include">0</Variable>
</Variables>
<Results>
<Result Name="0" VariableName="User.RS_Product" />
</Results>
<DirectInput>SELECT
*
FROM
(
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold);</DirectInput>
</ExecuteSQL>
<ForEachAdoLoop Name="FELC Shred Results" ConstraintMode="Linear" SourceVariableName="User.RS_Product">
<PrecedenceConstraints>
<Inputs>
<Input OutputPathName="SQL Get Rows.Output" SsisName="Constraint" />
</Inputs>
</PrecedenceConstraints>
<Tasks>
<ExecuteSQL Name="SQL Create Table if needed" ConnectionName="tempdb">
<VariableInput VariableName="User.Query_TableCreate" />
</ExecuteSQL>
<Dataflow Name="DFT Load Table" DelayValidation="true">
<Transformations>
<OleDbSource Name="OLE_SRC Get Data" DefaultCodePage="1252" ConnectionName="tempdb">
<VariableInput VariableName="User.Query_Source" />
</OleDbSource>
<OleDbDestination Name="OLE_DST Save data" ConnectionName="tempdb" >
<TableFromVariableOutput VariableName="User.TargetTable" />
<Columns>
<Column SourceColumn="ProductName" TargetColumn="ProductName" />
<Column SourceColumn="QuantitySold" TargetColumn="QuantitySold" />
</Columns>
</OleDbDestination>
</Transformations>
</Dataflow>
</Tasks>
<VariableMappings>
<VariableMapping Name="0" VariableName="User.ProductName" />
</VariableMappings>
</ForEachAdoLoop>
</Tasks>
<Connections>
<Connection ConnectionName="tempdb" />
</Connections>
</Package>
</Packages>
</Biml>