我不在 SSIS 中使用 temp table
I don't use temp table in SSIS
我在 SSIS 中使用 OLE-DB Source temp table 时遇到问题。
我在执行 T-SQL 语句任务中创建了临时 table 并更改了 DelayValidation:True 和 RetainSameConnection:True。但是问题并没有解决。
背景
这里可能发生的情况是 table 目前不存在。临时 table 有两种变体:本地和全局。
本地临时 table,使用的名称前面有一个 sharp/pound/hash/octothorpe,即 #TEMP
。唯一可以使用临时 table 实例的查询是创建它的查询。这就是为什么互联网上的建议说您需要将 RetainSameConnection
设置为 true 以确保创建 table 的连接在数据流中被重用。否则,您将受到连接池的支配,并且可能在两个地方都使用了相同的连接,也许没有,相信我,尝试和调试是一种令人不快的随机性。数据流上 DelayValidation
的原因是,当包启动时,引擎将在执行任何工作之前验证所有数据是否符合预期。由于前驱步骤是使数据流任务进入预期状态的步骤,因此我们需要告诉执行仅在执行前立即验证任务。验证总是会发生,这只是您何时支付价格的问题。
全局临时 table 定义前带有双 sharp/etc 符号 ##TEMP
。任何进程都可以访问它,而不仅仅是创建它的连接。它会一直存在,直到创建的连接消失(或明确删除它)。
分辨率
包设计完成后(元数据在数据流中建立),使用本地临时文件 table 就可以正常工作。虽然开发它,但不可能使用本地临时 table 作为数据流中的源。如果您执行前驱步骤,该连接将打开,创建临时 table 然后连接消失,临时 table.
我会通过以下步骤解决这个问题
- 将执行 SQL 任务中的查询复制到 SSMS 中的 window 并创建本地临时 table 作为全局临时 table,因此
##TEMP
.
- 创建一个名为 SourceQuery 的字符串类型的 SSIS 变量,值为
SELECT * FROM ##TEMP;
- 将 OLE DB 源的“数据访问模式”从“SQL 命令”修改为“SQL 来自变量的命令”并使用变量
User::SourceQuery
- 完成数据流的设计
- 保存包以确保元数据持久化
- 将变量中的查询从引用##TEMP 更改为#TEMP
- 再次保存。
- 删除##TEMP table 或关闭连接
- 运行 包确保一切如我所愿。
上面的第 2、3 和 6 步允许您模拟魔术师将 table布从所有盘子下面拉出来。
如果您手动将数据流中的查询从##TEMP 编辑为#TEMP,则会触发验证,并且由于没有可用的#TEMP table,它将报告VS_NEEDSNEWMETADATA 并且可能不会让您保存包裹。使用变量作为查询源提供了一种间接级别,使我们可以绕过“更改时验证”/重新初始化元数据步骤。
我在 SSIS 中使用 OLE-DB Source temp table 时遇到问题。
我在执行 T-SQL 语句任务中创建了临时 table 并更改了 DelayValidation:True 和 RetainSameConnection:True。但是问题并没有解决。
背景
这里可能发生的情况是 table 目前不存在。临时 table 有两种变体:本地和全局。
本地临时 table,使用的名称前面有一个 sharp/pound/hash/octothorpe,即 #TEMP
。唯一可以使用临时 table 实例的查询是创建它的查询。这就是为什么互联网上的建议说您需要将 RetainSameConnection
设置为 true 以确保创建 table 的连接在数据流中被重用。否则,您将受到连接池的支配,并且可能在两个地方都使用了相同的连接,也许没有,相信我,尝试和调试是一种令人不快的随机性。数据流上 DelayValidation
的原因是,当包启动时,引擎将在执行任何工作之前验证所有数据是否符合预期。由于前驱步骤是使数据流任务进入预期状态的步骤,因此我们需要告诉执行仅在执行前立即验证任务。验证总是会发生,这只是您何时支付价格的问题。
全局临时 table 定义前带有双 sharp/etc 符号 ##TEMP
。任何进程都可以访问它,而不仅仅是创建它的连接。它会一直存在,直到创建的连接消失(或明确删除它)。
分辨率
包设计完成后(元数据在数据流中建立),使用本地临时文件 table 就可以正常工作。虽然开发它,但不可能使用本地临时 table 作为数据流中的源。如果您执行前驱步骤,该连接将打开,创建临时 table 然后连接消失,临时 table.
我会通过以下步骤解决这个问题
- 将执行 SQL 任务中的查询复制到 SSMS 中的 window 并创建本地临时 table 作为全局临时 table,因此
##TEMP
. - 创建一个名为 SourceQuery 的字符串类型的 SSIS 变量,值为
SELECT * FROM ##TEMP;
- 将 OLE DB 源的“数据访问模式”从“SQL 命令”修改为“SQL 来自变量的命令”并使用变量
User::SourceQuery
- 完成数据流的设计
- 保存包以确保元数据持久化
- 将变量中的查询从引用##TEMP 更改为#TEMP
- 再次保存。
- 删除##TEMP table 或关闭连接
- 运行 包确保一切如我所愿。
上面的第 2、3 和 6 步允许您模拟魔术师将 table布从所有盘子下面拉出来。
如果您手动将数据流中的查询从##TEMP 编辑为#TEMP,则会触发验证,并且由于没有可用的#TEMP table,它将报告VS_NEEDSNEWMETADATA 并且可能不会让您保存包裹。使用变量作为查询源提供了一种间接级别,使我们可以绕过“更改时验证”/重新初始化元数据步骤。