到底是什么决定了 OLE DB 命令 (SSIS) 中参数的顺序。例如,我有一个如下所示的表格。
CREATE TABLE [dbo].[DimAppointmentFlags] (
[RowIdentifier] bigint PRIMARY KEY,
[AppointmentID] bigint,
[Flag] varchar(255)
)
GO
我在SSIS命令中运行的语句是:
UPDATE [dbo].[DimAppointmentFlags]
SET [AppointmentID] = ?,
[Flag] = ?
WHERE [RowIdentifier] = ?
我的第一个假设是它们处于现场顺序,即
RowIdentifier 为 Param_0 约会 ID 为 Param_1 标志是 Param_2
但我可以看到事实并非如此。能否详细说明一下,因为我发现官方文档没有那么有帮助:
OLE DB 连接管理器和 ODBC 连接管理器使用基于序数的令牌替换系统。代币是
?
。区别在于 OLE DB 使用基于零的计数系统,而 ODBC 使用基于一的计数系统。
在你的例子中
SET [AppointmentID] = ?,
[Flag] = ?
WHERE [RowIdentifier] = ?
第一个问号代表 AppointmentID,与
Param_0
(或仅在执行 SQL、OLE DB 源或查找组件中的 0
)值相关。
第二个 Flag,将与 Param_1 等相关。
让我们对您的查询采取稍微不同的变体。我们不只是更新行标识符为某个值的位置,而是仅在约会 ID 也是给定值时更新它。在这种情况下,基于序数的系统会变得愚蠢。
SET [AppointmentID] = ?,
[Flag] = ?
WHERE [RowIdentifier] = ?
-- ADDED THIS PART
AND [AppointmentID] = ?
第一个 AppointmentID 是序数零。 Flat 是序数一,RowIdentifier 是序数二,最后一个 ApppointmentID 是序数三。尽管两个地方都使用了“相同”的值,但它是一个“愚蠢”的系统,它实际上将每个标记替换一次。
为了完整起见,ADO 连接管理器使用命名参数,因此它看起来像这样
SET [AppointmentID] = @apptid,
[Flag] = @flag
WHERE [RowIdentifier] = @rowident
-- ADDED THIS PART
AND [AppointmentID] = @apptid;
在这里我们可以看到,当我们重用@apptid时,我们只有3个参数需要填充。
最后,在执行 SQL 命令和我认为 OLE DB 源(绝对不是 OLE DB 命令或查找)中,如果您发现自己需要通过声明 SQL 变量在查询中多次引用参数,则可以两全其美并从参数中填充它们。
DECLARE @apptid int = ?
, @flag bit = ?
, @rowident int = ?;
SET [AppointmentID] = @apptid,
[Flag] = @flag
WHERE [RowIdentifier] = @rowident
-- ADDED THIS PART
AND [AppointmentID] = @apptid;
现在我们有 3 个参数 OLE/ODBC 可以一次映射,但我们可以根据需要在查询正文中重用它们。作为奖励,您可以轻松地将其复制到您的查询工具中并进行测试。