在 Where 子句中包含用户变量的 SSIS 包
SSIS Package with User Variable in Where Clause
简而言之,我正在尝试获取用户输入,将其存储在一个变量中,然后在查询中使用该变量。
首先,我有一个脚本任务,它打开一个带有简单输入文本框和按钮的 window。单击时,文本被放入用户变量中,并弹出一个消息框以显示用户变量中的内容。单击消息框上的确定将关闭消息框和原始 window。这似乎工作正常。
接下来,我有一个执行 SQL 任务。设置如下:
一般
- 结果集 = None
- 连接类型 = OLE DB
- 连接 = localhost.DB
- SQLSourceType = 直接输入
- SQL语句=[SQL下面显示代码]
参数映射
- 变量名=User::VarName
- 方向=输入
- 数据类型 = VARCHAR
- 参数名称 = 0
- 参数大小 = 65535
结果集 - N/A
表达式 - N/A
[SQL代码]
if object_id('TEST.dbo.TEST','U') is not null
drop table TEST.dbo.TEST;
SELECT
coalesce(FSC.a, format(cast(SVY.b as int),'000')) as ab,
SVY.c,
PP.d,
SV1.e,
PP.f,
PP.g,
cast(PP.g as float) AS g,
SV1.h,
SV1.i,
SVY.j,
SVY.k,
format(cast(SVY.l as int), '00000') as l,
CAST(SVY.m AS float) AS m,
SVY.n,
SV1.o,
SVY.p,
cast(PID.q as float) as q,
cast(PID.r as float) as r,
cast(PID.s as float) as s,
cast(PID.t as float) as t,
PID.u as u,
PID.v as v,
PP.w,
CAL_B.x as x,
CAL_B.y as y,
CAL_B.z as z,
CAL_R.aa as aa,
CAL_R.bb as bb,
CAL_R.cc as cc
into TEST.dbo.TEST
FROM AAA.dbo.AAA PP
INNER JOIN BBB.dbo.BBB PPC
ON PP.x = PPC.x
AND cast(PP.x as date) = cast(PPC.x as date)
RIGHT OUTER JOIN CCC.dbo.CCC SVY
ON PPC.x = SVY.x
AND cast(PPC.x as date) = cast(SVY.x as date)
LEFT OUTER JOIN DDD.dbo.DDD FSC
ON SVY.x = FSC.x
AND cast(SVY.x as date) = cast(FSC.x as date)
LEFT OUTER JOIN EEE.dbo.EEE SV1
ON SVY.x = SV1.x
AND SVY.x = SV1.x
AND SVY.x = SV1.x
AND SVY.x = SV1.x
AND cast(SVY.x as date) = cast(SV1.x as date)
AND PPC.x = SV1.x
AND cast(PPC.x as date) = cast(SV1.x as date)
INNER JOIN FFF.dbo.FFF RLS
ON SV1.x = RLS.x
AND SV1.x = RLS.x
AND cast(SV1.x as date) = cast(RLS.x as date)
AND SVY.x = RLS.x
AND SVY.x = RLS.x
AND SVY.x = RLS.x
AND cast(SVY.x as date) = cast(RLS.x as date)
LEFT OUTER JOIN GGG.dbo.GGG PID
ON PP.x = PID.x
AND coalesce(FSC.x, format(cast(SVY.x as int),'000')) = PID.x
LEFT OUTER JOIN HHH.dbo.HHH CAL_B
ON cast('20' + SUBSTRING(RLS.x,4,2) + '-' + SUBSTRING(RLS.x,6,2) + '-' + SUBSTRING(RLS.x,8,2) as date) = CAL_B.x
AND CAL_B.x = 1
LEFT OUTER JOIN III.dbo.III CAL_R
ON cast('20' + SUBSTRING(RLS.x,4,2) + '-' + SUBSTRING(RLS.x,6,2) + '-' + SUBSTRING(RLS.x,8,2) as date) = CAL_R.x
AND CAL_R.x = 1
where
cast(SVY.x as date) = (select cast(max(x) as date) from JJJ.dbo.JJJ)
and
PP.x is not null
and
SVY.x in ( ? )
问题:我 运行 包裹。文本输入框打开。我输入文本“'CN05','CN06'”(不带双引号),然后单击“确定”。弹出框显示我的输入。我单击确定。工作流继续执行 SQL 任务。在 1 秒内,任务完成并显示绿色勾号,没有错误。我确认 TEST.dbo.TEST 已创建,但它是空的。
现在,如果我 运行 上面的代码在 SSMS 中硬编码最后一位 [...SVY.x in ('CN05','CN06')],我将返回超过 500 万条记录大约 4 分钟。我很困惑为什么这在 SSIS 中不起作用。有什么想法吗?
一般来说,参数化 WHERE IN
个子句 don't play nice。他们从不按照我们认为应该的方式工作。相反,您可以使用 SSIS 的动态 SQL 版本来实现相同的目的。创建一个字符串变量来存储较大的 SQL 语句与用户输入的串联。然后,连接您的 Execute SQL Task 以使用此变量。
例如,请创建一个名为 SqlStatement
的新 SSIS 字符串变量。在变量的属性 window 中,通过单击省略号打开表达式生成器 window。使用此表达式构建器将您的 SQL 与用户输入连接起来。下面的示例...
务必将变量的EvaluateAsExpression
属性设为True
。
最后,将执行 SQL 任务从直接输入更改为变量,并将 select 此变量作为源。
一切就绪。您的 Execute SQL 任务现在应该连接到使用您在表达式生成器中构建的动态 SQL。祝你好运!
简而言之,我正在尝试获取用户输入,将其存储在一个变量中,然后在查询中使用该变量。
首先,我有一个脚本任务,它打开一个带有简单输入文本框和按钮的 window。单击时,文本被放入用户变量中,并弹出一个消息框以显示用户变量中的内容。单击消息框上的确定将关闭消息框和原始 window。这似乎工作正常。
接下来,我有一个执行 SQL 任务。设置如下:
一般
- 结果集 = None
- 连接类型 = OLE DB
- 连接 = localhost.DB
- SQLSourceType = 直接输入
- SQL语句=[SQL下面显示代码]
参数映射
- 变量名=User::VarName
- 方向=输入
- 数据类型 = VARCHAR
- 参数名称 = 0
- 参数大小 = 65535
结果集 - N/A
表达式 - N/A
[SQL代码]
if object_id('TEST.dbo.TEST','U') is not null
drop table TEST.dbo.TEST;
SELECT
coalesce(FSC.a, format(cast(SVY.b as int),'000')) as ab,
SVY.c,
PP.d,
SV1.e,
PP.f,
PP.g,
cast(PP.g as float) AS g,
SV1.h,
SV1.i,
SVY.j,
SVY.k,
format(cast(SVY.l as int), '00000') as l,
CAST(SVY.m AS float) AS m,
SVY.n,
SV1.o,
SVY.p,
cast(PID.q as float) as q,
cast(PID.r as float) as r,
cast(PID.s as float) as s,
cast(PID.t as float) as t,
PID.u as u,
PID.v as v,
PP.w,
CAL_B.x as x,
CAL_B.y as y,
CAL_B.z as z,
CAL_R.aa as aa,
CAL_R.bb as bb,
CAL_R.cc as cc
into TEST.dbo.TEST
FROM AAA.dbo.AAA PP
INNER JOIN BBB.dbo.BBB PPC
ON PP.x = PPC.x
AND cast(PP.x as date) = cast(PPC.x as date)
RIGHT OUTER JOIN CCC.dbo.CCC SVY
ON PPC.x = SVY.x
AND cast(PPC.x as date) = cast(SVY.x as date)
LEFT OUTER JOIN DDD.dbo.DDD FSC
ON SVY.x = FSC.x
AND cast(SVY.x as date) = cast(FSC.x as date)
LEFT OUTER JOIN EEE.dbo.EEE SV1
ON SVY.x = SV1.x
AND SVY.x = SV1.x
AND SVY.x = SV1.x
AND SVY.x = SV1.x
AND cast(SVY.x as date) = cast(SV1.x as date)
AND PPC.x = SV1.x
AND cast(PPC.x as date) = cast(SV1.x as date)
INNER JOIN FFF.dbo.FFF RLS
ON SV1.x = RLS.x
AND SV1.x = RLS.x
AND cast(SV1.x as date) = cast(RLS.x as date)
AND SVY.x = RLS.x
AND SVY.x = RLS.x
AND SVY.x = RLS.x
AND cast(SVY.x as date) = cast(RLS.x as date)
LEFT OUTER JOIN GGG.dbo.GGG PID
ON PP.x = PID.x
AND coalesce(FSC.x, format(cast(SVY.x as int),'000')) = PID.x
LEFT OUTER JOIN HHH.dbo.HHH CAL_B
ON cast('20' + SUBSTRING(RLS.x,4,2) + '-' + SUBSTRING(RLS.x,6,2) + '-' + SUBSTRING(RLS.x,8,2) as date) = CAL_B.x
AND CAL_B.x = 1
LEFT OUTER JOIN III.dbo.III CAL_R
ON cast('20' + SUBSTRING(RLS.x,4,2) + '-' + SUBSTRING(RLS.x,6,2) + '-' + SUBSTRING(RLS.x,8,2) as date) = CAL_R.x
AND CAL_R.x = 1
where
cast(SVY.x as date) = (select cast(max(x) as date) from JJJ.dbo.JJJ)
and
PP.x is not null
and
SVY.x in ( ? )
问题:我 运行 包裹。文本输入框打开。我输入文本“'CN05','CN06'”(不带双引号),然后单击“确定”。弹出框显示我的输入。我单击确定。工作流继续执行 SQL 任务。在 1 秒内,任务完成并显示绿色勾号,没有错误。我确认 TEST.dbo.TEST 已创建,但它是空的。 现在,如果我 运行 上面的代码在 SSMS 中硬编码最后一位 [...SVY.x in ('CN05','CN06')],我将返回超过 500 万条记录大约 4 分钟。我很困惑为什么这在 SSIS 中不起作用。有什么想法吗?
一般来说,参数化 WHERE IN
个子句 don't play nice。他们从不按照我们认为应该的方式工作。相反,您可以使用 SSIS 的动态 SQL 版本来实现相同的目的。创建一个字符串变量来存储较大的 SQL 语句与用户输入的串联。然后,连接您的 Execute SQL Task 以使用此变量。
例如,请创建一个名为 SqlStatement
的新 SSIS 字符串变量。在变量的属性 window 中,通过单击省略号打开表达式生成器 window。使用此表达式构建器将您的 SQL 与用户输入连接起来。下面的示例...
务必将变量的EvaluateAsExpression
属性设为True
。
最后,将执行 SQL 任务从直接输入更改为变量,并将 select 此变量作为源。
一切就绪。您的 Execute SQL 任务现在应该连接到使用您在表达式生成器中构建的动态 SQL。祝你好运!