SSIS包-根据数据从一个表到无限表
我有一个简单的要求。我有一张表,上面有产品名称和数量。我想创建一个SSIS包,根据产品名称将数据从一个表提取到无限多个表。 在表中,若我有10个产品,那个么SSIS包应该动态创建10个表,每个表中有一个产品SSIS包-根据数据从一个表到无限表,ssis,Ssis,我有一个简单的要求。我有一张表,上面有产品名称和数量。我想创建一个SSIS包,根据产品名称将数据从一个表提取到无限多个表。 在表中,若我有10个产品,那个么SSIS包应该动态创建10个表,每个表中有一个产品 ProductName , QuantitySold ABC 10 表名:产品 ProductName , QuantitySold ABC 10 xyz 15 Testing
ProductName , QuantitySold
ABC 10
表名:产品
ProductName , QuantitySold
ABC 10
xyz 15
Testing 25
ProductName , QuantitySold
ABC 10
表格名称:ABC
ProductName , QuantitySold
ABC 10
表名:XYZ
ProductName , QuantitySold
ABC 10
ProductName , QuantitySold
xyz 15
表名:测试
ProductName , QuantitySold
ABC 10
ProductName , QuantitySold
ABC 10
从概念上讲,你看到的是
ProductName , QuantitySold
ABC 10
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
ProductName , QuantitySold
ABC 10
其概念是,您将标识表中的所有产品名称,并在每一行上执行两个任务:如果需要,创建目标表。对该行的源运行查询并将其加载到表中
ProductName , QuantitySold
ABC 10
变量
我声明了6个变量
ProductName , QuantitySold
ABC 10
ProductName , QuantitySold
ABC 10
Query\u TableCreateBase是一个大字符串,其格式如下
ProductName , QuantitySold
ABC 10
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
SELECT ProductName, QuantitySold FROM (
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold) WHERE ProductName = 'Foo'
查询表创建表达式
ProductName , QuantitySold
ABC 10
"SELECT ProductName, QuantitySold FROM (
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold) WHERE ProductName = '" + @[User::ProductName] + "'"
replace(@[User::Query_TableCreateBase], "<Table/>", @[User::ProductName])
"[dbo].[" +@[User::ProductName] + "]"
SQL获取行
我用一个查询模拟您的Products表。我将这些结果加载到一个名为RS_Product的变量中
ProductName , QuantitySold
ABC 10
SELECT
ProductName
FROM
(
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold);
FELC分解结果
我使用Foreach循环容器,设置为处理ADO结果集,并将第0列解析为我们的ProductName变量
ProductName , QuantitySold
ABC 10
SQL创建表(如果需要)
这是一个查询,其计算结果如下
ProductName , QuantitySold
ABC 10
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
DFT载荷表
我将此设置为DelayValidation=true,因为在收到启动信号之前,表可能不存在
ProductName , QuantitySold
ABC 10
再次模拟Products表,我的查询如下所示
ProductName , QuantitySold
ABC 10
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
SELECT ProductName, QuantitySold FROM (
VALUES
('ABC', 10)
, ('xyz', 15)
, ('Testing', 25)
) Products(ProductName, QuantitySold) WHERE ProductName = 'Foo'
拉普
严格来说,不需要数据流。如果我们收回源查询中的所有列,那么这一切都可以通过执行SQL任务来完成
ProductName , QuantitySold
ABC 10
Biml实现
商业智能标记语言Biml描述了商业智能平台。在这里,我们将用它来描述ETL,是VisualStudio/BIDS/SSDT的免费附加组件,解决了它的许多缺点。具体来说,我们将使用将描述ETL的Biml文件转换为SSIS包的功能。这还有一个额外的好处,即为您提供了一种机制,使您能够准确地生成我所描述的解决方案,而不是单击许多冗长的对话框
ProductName , QuantitySold
ABC 10
下面的代码假设您在本地计算机上有一个默认实例,并且在tempdb中有一个名为Foo的表
ProductName , QuantitySold
ABC 10
use tempdb;
GO
CREATE TABLE dbo.Foo
(
ProductName varchar(30) NOT NULL
, QuantitySold int NOT NULL
);
将以下脚本保存到.biml文件中,添加到SSIS项目时,该文件将显示在杂项虚拟文件夹下。右键单击,选择生成SSIS包,它应该创建一个名为so_27320726
ProductName , QuantitySold
ABC 10
<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>
福
“选择ProductName,QuantitySelled FROM”(
价值观
('ABC',10)
,('xyz',15)
,(“测试”,25)
)产品(ProductName,QuantitySelled),其中ProductName='+@[User::ProductName]+''
(
ProductName varchar(30)不为空
,QuantitySeld int不为空
);
结束]]>
“[dbo]。”+@[User::ProductName]+“]”
0
挑选
*
从…起
(
价值观
('ABC',10)
,('xyz',15)
,(“测试”,25)
)产品(产品名称、已售出数量);
真的吗?一个表,根据该表中的值,您将创建一个包含1行的2列表?是的,根据要求,您不知道该如何做?事实上,你为什么还要使用SSI?@Ally这真是一个奇怪的要求。我的意思是你可以训练用户如何使用WHERE子句。它必须是这个精确解吗?