如何在 SSIS 控制流任务中创建临时 table 然后在 VAL 流任务中使用它?
How to create a temporary table in SSIS control flow task and then use it in VAL flow task?
我有一个控制流,我在其中创建了一个临时数据库,并使用 T-SQL 命令 table。当我添加数据流时,我想查询 table 但我不能,因为 table 不存在以获取信息。当我尝试时,我收到有关登录的错误,因为数据库(还)不存在。我延迟验证为真。
如果我创建数据库并 table 手动然后添加带有查询的数据流并删除它保留的数据库,但这似乎不是一个干净的解决方案。
如果有更好的方法来创建临时登台数据库并在数据流中查询它,请告诉我。
如果你绝对必须有一个数据库,它只在你的包执行的瞬间存在,那么这样做......你的第一个控制流项目是一个创建数据库的执行 SQL 语句。随后是另一个创建 table 的 Execute SQL 语句。接下来,将您的数据流放入 table 和您的查询中。最后,作为最后一个控制流项目,使用 DROP 数据库命令执行 SQL 语句。完成,临时数据库。
对此的警告 - 如您所见 - 是为了设计数据流,数据库必须首先存在。没有办法解决这个问题。我们设计数据流所针对的对象必须存在才能设计它。但是,这个问题只存在于设计阶段。这是暂时的。数据流设计完成后,您可以保存包并删除数据库。它会一直消失,直到您再次 运行 包裹。设置 "delay validation" 可确保您的数据流不会尝试验证包顶部的数据库是否存在。在您的 CREATE 数据库语句之后,它会在需要之前等待。所以你在那里很好。
但是,在您实施此设计之前,我必须先问一下。为什么我们像使用变量一样使用数据库?为什么创建它只是为了稍后删除它?我要冒昧地猜测我们这样做是因为您希望将数据放在 SQL 中,您可以在其中利用 SQL 语言有选择地查询 and/or 操作它?如果是这样的话,SSIS 的目的就是使用提供的数据流转换工具进行这种类型的操作或查询。另外,您没有在问题中提及它,但是数据的最终目的地是什么?我们不只是将其加载到数据库中以将其删除。那么它最终会在哪里呢?平面文件?
解决方法:
将连接管理器上的 属性 RetainSameConnection 设置为 True,以便在一个控制流任务中创建的临时 table 可以保留在另一个任务中。
这是一个用 SSIS 2008 R2 编写的示例 SSIS 包,它说明了如何使用临时 tables。
演练:
创建一个存储过程,该过程将创建一个名为 ##tmpStateProvince 的临时 table 并填充少量记录。示例 SSIS 包将首先调用存储过程,然后获取临时 table 数据以将记录填充到另一个数据库 table。示例包将使用名为 Sora 的数据库使用下面的创建存储过程脚本。
USE Sora;
GO
CREATE PROCEDURE dbo.PopulateTempTable
AS
BEGIN
SET NOCOUNT ON;
IF OBJECT_ID('TempDB..##tmpStateProvince') IS NOT NULL
DROP TABLE ##tmpStateProvince;
CREATE TABLE ##tmpStateProvince
(
CountryCode nvarchar(3) NOT NULL
, StateCode nvarchar(3) NOT NULL
, Name nvarchar(30) NOT NULL
);
INSERT INTO ##tmpStateProvince
(CountryCode, StateCode, Name)
VALUES
('CA', 'AB', 'Alberta'),
('US', 'CA', 'California'),
('DE', 'HH', 'Hamburg'),
('FR', '86', 'Vienne'),
('AU', 'SA', 'South Australia'),
('VI', 'VI', 'Virgin Islands');
END
GO
Create a table named dbo.StateProvince that will be used as the destination table to populate the records from temporary table. Use the below create table script to create the destination table.
USE Sora;
GO
CREATE TABLE dbo.StateProvince
(
StateProvinceID int IDENTITY(1,1) NOT NULL
, CountryCode nvarchar(3) NOT NULL
, StateCode nvarchar(3) NOT NULL
, Name nvarchar(30) NOT NULL
CONSTRAINT [PK_StateProvinceID] PRIMARY KEY CLUSTERED
([StateProvinceID] ASC)
) ON [PRIMARY];
GO
使用 Business Intelligence Development Studio (BIDS) 创建 SSIS 包。右键单击包底部的“连接管理器”选项卡,然后单击“新建 OLE DB 连接...”以创建新连接以访问 SQL Server 2008 R2 数据库。
在“配置 OLE DB 连接管理器”上单击“新建...”。
在“连接管理器”对话框中执行以下操作。
Select 本机 OLE DB\SQL 来自提供商的服务器本机客户端 10.0
因为软件包将连接到 SQL Server 2008 R2 数据库
输入服务器名称,如MACHINENAME\INSTANCE
- Select 使用 Windows 从登录到服务器部分或任何您喜欢的身份验证。
- Select数据库来自Select或输入数据库名称,
示例使用数据库名称 Sora。
- 单击测试连接
- 在“测试连接成功”消息上单击“确定”。
- 在连接管理器上单击“确定”
新创建的数据连接将出现在配置 OLE DB 连接管理器上。单击“确定”。
OLE DB 连接管理器KIWI\SQLSERVER2008R2.Sora 将出现在包底部的“连接管理器”选项卡下。右键单击连接管理器并单击属性
将连接 KIWI\SQLSERVER2008R2.Sora 上的 属性 RetainSameConnection 设置为值 True。
右键单击包内的任意位置,然后单击“变量”以查看变量窗格。创建以下变量。
包范围 SO_5631010 中数据类型为 String 的名为 PopulateTempTable 的新变量,并将该变量设置为值 EXEC dbo.PopulateTempTable。
包范围 SO_5631010 中数据类型为 String 的名为 FetchTempData 的新变量,并将变量设置为值 SELECT CountryCode, StateCode, Name FROM ##tmpStateProvince
将执行 SQL 任务拖放到“控制流”选项卡上。双击执行 SQL 任务以查看执行 SQL 任务编辑器。
在执行 SQL 任务编辑器的常规页面上,执行以下操作。
将名称设置为 Create 并填充 temp table
将连接类型设置为 OLE DB
将连接设置为 KIWI\SQLSERVER2008R2.Sora
Select 来自 SQLSourceType 的变量
Select User::PopulateTempTable 来自 SourceVariable
单击确定
将数据流任务拖放到“控制流”选项卡上。将数据流任务重命名为将临时数据传输到数据库 table。将绿色箭头从执行 SQL 任务连接到数据流任务。
双击数据流任务切换到数据流选项卡。将 OLE DB 源拖放到数据流选项卡上。双击 OLE DB 源以查看 OLE DB 源编辑器。
在 OLE DB 源编辑器的连接管理器页面上,执行以下操作。
Select KIWI\SQLSERVER2008R2.Sora 来自 OLE DB 连接管理器
Select SQL 来自数据访问模式变量的命令
Select User::FetchTempData 来自变量名
单击列页面
在 OLE DB 源代码编辑器上单击“列”页面将显示以下错误,因为 table 在源命令变量中指定的##tmpStateProvince 不存在并且 SSIS 无法读取列定义。
要修复错误,请使用 SQL Server Management Studio (SSMS) 在数据库 Sora 上执行语句 EXEC dbo.PopulateTempTable,以便存储过程将创建临时 table。执行存储过程后,在OLE DB Source Editor 中点击Columns 页面,您将看到列信息。单击“确定”。
将 OLE DB 目标拖放到“数据流”选项卡上。将绿色箭头从 OLE DB 源连接到 OLE DB 目标。双击 OLE DB 目标以打开 OLE DB 目标编辑器。
在 OLE DB 目标编辑器的连接管理器页面上,执行以下操作。
Select KIWI\SQLSERVER2008R2.Sora 来自 OLE DB 连接管理器
Select Table 或视图 - 从数据访问模式快速加载
Select [dbo].[StateProvince] 来自 table 或视图的名称
单击映射页面
如果输入和输出列名称相同,单击 OLE DB 目标编辑器上的映射页面将自动映射列。单击确定。列 StateProvinceID 没有匹配的输入列,它被定义为数据库中的 IDENTITY 列。因此,不需要映射。
配置所有组件后,“数据流”选项卡应如下所示。
单击“数据流”选项卡上的“OLE DB 源”,然后按 F4 键查看“属性”。将 属性 ValidateExternalMetadata 设置为 False,这样 SSIS 就不会在包执行的验证阶段尝试检查临时 table 的存在。
在 SQL Server Management Studio (SSMS) 中执行查询 select * from dbo.StateProvince 以查找 table 中的行数。在执行包之前它应该是空的。
执行包。控制流显示执行成功。
在“数据流”选项卡中,您会注意到包成功处理了 6 行。这篇文章前面创建的存储过程将 6 行插入临时 table.
在 SQL Server Management Studio (SSMS) 中执行查询 select * from dbo.StateProvince 以找到成功插入 table 的 6 行。数据应与存储过程中找到的行相匹配。
以上示例说明了如何在包
中创建和使用临时 table
我有一个控制流,我在其中创建了一个临时数据库,并使用 T-SQL 命令 table。当我添加数据流时,我想查询 table 但我不能,因为 table 不存在以获取信息。当我尝试时,我收到有关登录的错误,因为数据库(还)不存在。我延迟验证为真。
如果我创建数据库并 table 手动然后添加带有查询的数据流并删除它保留的数据库,但这似乎不是一个干净的解决方案。
如果有更好的方法来创建临时登台数据库并在数据流中查询它,请告诉我。
如果你绝对必须有一个数据库,它只在你的包执行的瞬间存在,那么这样做......你的第一个控制流项目是一个创建数据库的执行 SQL 语句。随后是另一个创建 table 的 Execute SQL 语句。接下来,将您的数据流放入 table 和您的查询中。最后,作为最后一个控制流项目,使用 DROP 数据库命令执行 SQL 语句。完成,临时数据库。
对此的警告 - 如您所见 - 是为了设计数据流,数据库必须首先存在。没有办法解决这个问题。我们设计数据流所针对的对象必须存在才能设计它。但是,这个问题只存在于设计阶段。这是暂时的。数据流设计完成后,您可以保存包并删除数据库。它会一直消失,直到您再次 运行 包裹。设置 "delay validation" 可确保您的数据流不会尝试验证包顶部的数据库是否存在。在您的 CREATE 数据库语句之后,它会在需要之前等待。所以你在那里很好。
但是,在您实施此设计之前,我必须先问一下。为什么我们像使用变量一样使用数据库?为什么创建它只是为了稍后删除它?我要冒昧地猜测我们这样做是因为您希望将数据放在 SQL 中,您可以在其中利用 SQL 语言有选择地查询 and/or 操作它?如果是这样的话,SSIS 的目的就是使用提供的数据流转换工具进行这种类型的操作或查询。另外,您没有在问题中提及它,但是数据的最终目的地是什么?我们不只是将其加载到数据库中以将其删除。那么它最终会在哪里呢?平面文件?
解决方法: 将连接管理器上的 属性 RetainSameConnection 设置为 True,以便在一个控制流任务中创建的临时 table 可以保留在另一个任务中。 这是一个用 SSIS 2008 R2 编写的示例 SSIS 包,它说明了如何使用临时 tables。 演练: 创建一个存储过程,该过程将创建一个名为 ##tmpStateProvince 的临时 table 并填充少量记录。示例 SSIS 包将首先调用存储过程,然后获取临时 table 数据以将记录填充到另一个数据库 table。示例包将使用名为 Sora 的数据库使用下面的创建存储过程脚本。
USE Sora;
GO
CREATE PROCEDURE dbo.PopulateTempTable
AS
BEGIN
SET NOCOUNT ON;
IF OBJECT_ID('TempDB..##tmpStateProvince') IS NOT NULL
DROP TABLE ##tmpStateProvince;
CREATE TABLE ##tmpStateProvince
(
CountryCode nvarchar(3) NOT NULL
, StateCode nvarchar(3) NOT NULL
, Name nvarchar(30) NOT NULL
);
INSERT INTO ##tmpStateProvince
(CountryCode, StateCode, Name)
VALUES
('CA', 'AB', 'Alberta'),
('US', 'CA', 'California'),
('DE', 'HH', 'Hamburg'),
('FR', '86', 'Vienne'),
('AU', 'SA', 'South Australia'),
('VI', 'VI', 'Virgin Islands');
END
GO
Create a table named dbo.StateProvince that will be used as the destination table to populate the records from temporary table. Use the below create table script to create the destination table.
USE Sora;
GO
CREATE TABLE dbo.StateProvince
(
StateProvinceID int IDENTITY(1,1) NOT NULL
, CountryCode nvarchar(3) NOT NULL
, StateCode nvarchar(3) NOT NULL
, Name nvarchar(30) NOT NULL
CONSTRAINT [PK_StateProvinceID] PRIMARY KEY CLUSTERED
([StateProvinceID] ASC)
) ON [PRIMARY];
GO
使用 Business Intelligence Development Studio (BIDS) 创建 SSIS 包。右键单击包底部的“连接管理器”选项卡,然后单击“新建 OLE DB 连接...”以创建新连接以访问 SQL Server 2008 R2 数据库。
在“配置 OLE DB 连接管理器”上单击“新建...”。
在“连接管理器”对话框中执行以下操作。
Select 本机 OLE DB\SQL 来自提供商的服务器本机客户端 10.0
因为软件包将连接到 SQL Server 2008 R2 数据库输入服务器名称,如MACHINENAME\INSTANCE
- Select 使用 Windows 从登录到服务器部分或任何您喜欢的身份验证。
- Select数据库来自Select或输入数据库名称, 示例使用数据库名称 Sora。
- 单击测试连接
- 在“测试连接成功”消息上单击“确定”。
- 在连接管理器上单击“确定”
新创建的数据连接将出现在配置 OLE DB 连接管理器上。单击“确定”。
OLE DB 连接管理器KIWI\SQLSERVER2008R2.Sora 将出现在包底部的“连接管理器”选项卡下。右键单击连接管理器并单击属性
将连接 KIWI\SQLSERVER2008R2.Sora 上的 属性 RetainSameConnection 设置为值 True。
右键单击包内的任意位置,然后单击“变量”以查看变量窗格。创建以下变量。 包范围 SO_5631010 中数据类型为 String 的名为 PopulateTempTable 的新变量,并将该变量设置为值 EXEC dbo.PopulateTempTable。 包范围 SO_5631010 中数据类型为 String 的名为 FetchTempData 的新变量,并将变量设置为值 SELECT CountryCode, StateCode, Name FROM ##tmpStateProvince
将执行 SQL 任务拖放到“控制流”选项卡上。双击执行 SQL 任务以查看执行 SQL 任务编辑器。 在执行 SQL 任务编辑器的常规页面上,执行以下操作。 将名称设置为 Create 并填充 temp table 将连接类型设置为 OLE DB 将连接设置为 KIWI\SQLSERVER2008R2.Sora Select 来自 SQLSourceType 的变量 Select User::PopulateTempTable 来自 SourceVariable 单击确定
将数据流任务拖放到“控制流”选项卡上。将数据流任务重命名为将临时数据传输到数据库 table。将绿色箭头从执行 SQL 任务连接到数据流任务。
双击数据流任务切换到数据流选项卡。将 OLE DB 源拖放到数据流选项卡上。双击 OLE DB 源以查看 OLE DB 源编辑器。 在 OLE DB 源编辑器的连接管理器页面上,执行以下操作。 Select KIWI\SQLSERVER2008R2.Sora 来自 OLE DB 连接管理器 Select SQL 来自数据访问模式变量的命令 Select User::FetchTempData 来自变量名 单击列页面
在 OLE DB 源代码编辑器上单击“列”页面将显示以下错误,因为 table 在源命令变量中指定的##tmpStateProvince 不存在并且 SSIS 无法读取列定义。
要修复错误,请使用 SQL Server Management Studio (SSMS) 在数据库 Sora 上执行语句 EXEC dbo.PopulateTempTable,以便存储过程将创建临时 table。执行存储过程后,在OLE DB Source Editor 中点击Columns 页面,您将看到列信息。单击“确定”。
将 OLE DB 目标拖放到“数据流”选项卡上。将绿色箭头从 OLE DB 源连接到 OLE DB 目标。双击 OLE DB 目标以打开 OLE DB 目标编辑器。 在 OLE DB 目标编辑器的连接管理器页面上,执行以下操作。 Select KIWI\SQLSERVER2008R2.Sora 来自 OLE DB 连接管理器 Select Table 或视图 - 从数据访问模式快速加载 Select [dbo].[StateProvince] 来自 table 或视图的名称 单击映射页面
如果输入和输出列名称相同,单击 OLE DB 目标编辑器上的映射页面将自动映射列。单击确定。列 StateProvinceID 没有匹配的输入列,它被定义为数据库中的 IDENTITY 列。因此,不需要映射。
配置所有组件后,“数据流”选项卡应如下所示。
单击“数据流”选项卡上的“OLE DB 源”,然后按 F4 键查看“属性”。将 属性 ValidateExternalMetadata 设置为 False,这样 SSIS 就不会在包执行的验证阶段尝试检查临时 table 的存在。
在 SQL Server Management Studio (SSMS) 中执行查询 select * from dbo.StateProvince 以查找 table 中的行数。在执行包之前它应该是空的。
执行包。控制流显示执行成功。
在“数据流”选项卡中,您会注意到包成功处理了 6 行。这篇文章前面创建的存储过程将 6 行插入临时 table.
在 SQL Server Management Studio (SSMS) 中执行查询 select * from dbo.StateProvince 以找到成功插入 table 的 6 行。数据应与存储过程中找到的行相匹配。
以上示例说明了如何在包
中创建和使用临时 table