查询中的对象变量

Object Variable in a query

我正在使用 SSDT 2017,我正在研究一个基本上从查询中获取完整结果集到变量中的解决方案(仅 1 列:AccountID),我需要将该对象变量中的值包含在一个查询,像这样:

"SELECT * FROM dbo.account WHERE AccountID IN (" + @AccountIDObjectVariable + ")"

我尝试了一个表达式但是我得到了一个错误,所以我不确定是否有更好的方法,我也尝试了一个 for each 循环容器逻辑但是因为我在对象变量中有数百万条记录我认为这是不是最好的方法。

有什么想法吗?

这样不行。其中“它”将成为一大堆东西。

SSIS 数据类型是原始类型(布尔值、日期、数字)或对象。 Object 唯一支持的操作是 null 检查和枚举。

SSIS 参数化仅适用于基于相等的替换。 SQL 中没有列表数据类型的概念,因此 SSIS 中没有类似物。

I have millions of record in the object variable

即使您将列表转换为字符串并使用字符串连接,您要运行遇到的下一个问题是 4000 个字符的字符串长度限制。

路在何方?

让我们重设问题:您有一组来自源系统的重要身份。该组 id 需要用作后续提取的基础。

身份来源和实际数据是否在同一台服务器上

虽然您可以用茶匙清空海洋,但这不是正确的工具。这里也是一样。将标识要提取的记录集的查询移动到源的筛选条件中。

即 将数据集加载到@AccountIDObjectVariable

SELECT
    OA.AccountId
FROM
    dbo.OutstandingAccount AS OA;

提取无效

"SELECT * FROM dbo.account WHERE AccountID IN (" + @AccountIDObjectVariable + ")"

改写为

SELECT * FROM dbo.account AS A WHERE EXISTS (SELECT * FROM dbo.OutstandingAccount AS OA WHERE OA.AccountID = A.AccountID);

有两种合理的方法可以解决这个问题

全力以赴

如果来源 ID 列表和来源 table 的数量级相似,则将其全部删除并在查找任务中使用帐户 ID 生成查询可能会更容易。如果 AccountID 存在,那么它就是您想要的数据。是的,你拉的比你想要的多,但你可能会消耗更多的周期和复杂性来尝试select主动拉你想要的东西。

推拉

这种方法适用于 SQL 服务器,我不知道任何其他数据库。好吧,我想 Sybase 与数据库父子关系相同。

打开 SSMS 并在 dbo.account 所在的数据库上创建一个全局临时 table。不要断开与 SSMS 的连接。

IF OBJECT_ID('tempdb..##SO_66961235') IS NOT NULL
BEGIN
    DROP TABLE ##SO_66961235;
END
GO
CREATE TABLE ##SO_66961235
(
    AccountID int NOT NULL
);

修改连接管理器,将数据库连接的 RetainSameConnection 属性 设置为 true dbo.account

执行 SQL 任务 - 制作临时文件 Table 使用与帐户数据库的连接和上述查询。这将确保 table 存在,以便 SSIS 的未来会话正常工作。

DataFlow 加载 ID 在数据流属性中,将 DelayValidation 设置为 True

使用源查询生成 ID 列表,select 临时 table 作为目标。您 可能 需要有第二个连接管理器到此系统 运行ning 并指向 tempdb,我已经很久没有这样做了。关于 RetainSameConnection 的相同规则将适用。

此数据流完成后,我们将在数据源服务器上有一个临时的 table 供我们参考。

数据流 2 获取数据 同样,DelayValidation 为真。

源将是一个查询

SELECT * FROM dbo.account AS A WHERE EXISTS (SELECT * FROM ##SO_66961235 AS OA WHERE OA.AccountID = A.AccountID);

所有延迟验证是怎么回事?

当 SSIS 程序包启动时,首先 它所做的事情是确保所有部分都已就位,以便 运行 成功,而不仅仅是这些部分在地方,数据的形状还是一样的吗?程序包启动时临时 table 将不存在,程序包将失败并出现 VS_NEEDSNEWMETADATA 错误。设置 DelayValidation 告诉 SSIS 它不应该担心检查,直到组件在检查元数据之前实际获得启动信号。由于我们定义了前体 Execute SQL Task 来创建 table,因此验证应该成功。

我在这里使用了全局临时 tables。您可以使用局部范围的临时 tables 但这会使本已繁琐的设计过程变得更加复杂。如果是我,我会有一个控制布尔值的包参数,该布尔值使用全局温度 table 进行开发会话,使用本地温度 table 进行实际 运行 时间操作,但这超出了范围这个问题。