Sql server 作为参数值的串联字符串不会在存储过程中给出输出
我正在使用SQL SERVER 2008管理工作室。Sql server 作为参数值的串联字符串不会在存储过程中给出输出,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我正在使用SQL SERVER 2008管理工作室。 我有一个接受多个参数的存储过程。 一个参数名为@recvemail,默认值为'B' 如果@recvemail的值为'Y',则输出中应显示选择电子邮件新闻信函的所有用户。 如果@recvemail为'N',则不希望接收电子邮件的用户应包括在输出中。 如果值为'B',则输出中应显示所有用户, 无论是选择新闻信函还是不选择新闻信函 现在,对于默认值'B',我尝试将参数参数值设置为'Y','N',但没有得到任何输出 我的存储过程是 Create pr
我有一个接受多个参数的存储过程。
一个参数名为
@recvemail
,默认值为'B'
如果
@recvemail
的值为'Y'
,则输出中应显示选择电子邮件新闻信函的所有用户。如果
@recvemail
为'N'
,则不希望接收电子邮件的用户应包括在输出中。如果值为
'B'
,则输出中应显示所有用户,
无论是选择新闻信函还是不选择新闻信函
现在,对于默认值'B'
,我尝试将参数参数值设置为'Y'
,'N'
,但没有得到任何输出
我的存储过程是
Create procedure [dbo].[proc_getMembershipEmailbackup]
-- exec proc_getMembershipEmail @From=N'1991-06-11',@To=N'2017-06-14',@DevoteeName=N'',@MembershipName=N'Membership Life',@log_cond=N'',@recvemail=N'N'
@From varchar(10),
@To varchar(10),
@DevoteeName varchar(60)='',
@MembershipName varchar(100)='ALL',
@Email varchar(50)= '',
@Phoneno varchar(50)= '',
@MinAmount decimal =Null,
@MaxAmount decimal =NULL,
@log_cond Varchar(5),
@recvemail char(61)='B'
As
Begin
if @recvemail = 'B'
Begin
Set @recvemail='Y' + ',' + 'N'
End
end
Begin
if @MembershipName = 'ALL'
Begin
Set @MembershipName=''
End
end
begin
select
ROW_NUMBER() over (order by mu.f_name) as [No],
mu.f_name +' '+mu.l_name as DevoteeName ,
mu.pers_email as Email,
mu.home_phone as PhoneNo,
mp.name as MembershipName,
mu.recv_email as optedforemail,
d1.memb_id ,
d1.amt_due as amount_due,
CONVERT(varchar(10),d1.nextduedate,101) as duedate,
d1.pay_term
from d_user_memb d1
left join m_user mu on d1.user_id = mu.user_id
left join m_memb_pledge mp on d1.memb_id = mp.memb_id
where
d1.status in ('A','D','C')
AND(Isnull(@From,'') = '' or CONVERT(date,d1.nextduedate ) >= CONVERT(date,@From) )
and (Isnull(@To,'') = '' or CONVERT(date,d1.nextduedate ) <= CONVERT(date,@To ))
and (Isnull(@DevoteeName,'') = '' or (f_name +' '+l_name) like '%' + @DevoteeName + '%')
and (recv_email in (@recvemail ) )
and (Isnull(@MembershipName,'') = '' or (mp.name) = @MembershipName)
and (ISNULL (@Email, '') = '' or mu.pers_email = @Email)
and (ISNULL (@Phoneno, '') = '' or mu.home_phone = @Phoneno)
--and (ISNULL (@MinAmount,0) = 0 or cast(d1.amt_due as decimal(10,2)) >=@MinAmount)
--and (ISNULL (@MaxAmount, 0) =0 or cast(d1.amt_due as decimal(10,2)) <= @MaxAmount)
and d1.amt_due<>0
and mu.status='A'
and (
(
@log_cond = 'b'
AND d1.amt_due BETWEEN @MinAmount AND @MaxAmount
)
OR
(
@log_cond <> 'b'
AND @log_cond <> '0'
AND
(
isnull(@log_cond,'')=''
OR (@log_cond = '>' AND d1.amt_due > @MinAmount)
OR (@log_cond = '<' AND d1.amt_due < @MinAmount)
OR (@log_cond = '>=' AND d1.amt_due >= @MinAmount)
OR (@log_cond = '<=' AND d1.amt_due <= @MinAmount)
OR (@log_cond='=' AND d1.amt_due =@MinAmount)
)
)
OR
(
ISNULL(@log_cond,'')='0'
)
)
End
如果将参数值@recvemail
从'B'
更改为'Y'
,我将正确获得输出,并且所有选择电子邮件的用户都将正确显示在输出中。类似地,我将值从
'B'
更改为'N'
我正确获得了输出,并且所有未选择电子邮件的用户都显示在输出中。仅针对值
'B'
我没有得到输出。我应该获得输出,这样所有选择或未选择电子邮件的用户都应该出现在输出中。如中所述,in()
操作符需要一个逗号分隔的参数列表,但您提供了一个包含逗号分隔的值列表的参数
更改存储过程的这一部分:
and (recv_email in (@recvemail ) )
为此:
and (recv_email = @recvemail OR @recvemail = 'B')
如中所述,in()
运算符需要一个逗号分隔的参数列表,但您为它提供了一个包含逗号分隔的值列表的参数
更改存储过程的这一部分:
and (recv_email in (@recvemail ) )
为此:
and (recv_email = @recvemail OR @recvemail = 'B')
线路
and (recv_email in (@recvemail ) )
相当于
and recv_email = @recvemail
中的用于仅传递一个参数的参数列表。它不会解析参数的内容以查看是否有任何参数可以解释为逗号分隔的列表
如果要对照选项列表进行检查,请创建一个表值参数,并在in
子句中使用它:
declare @emailoptions table (Option varchar(2))
IF (@recvemail = 'B' OR @recvemail = 'Y')
begin
insert into @emailoptions VALUES('Y')
end if
IF (@recvemail = 'B' OR @recvemail = 'N')
begin
insert into @emailoptions VALUES('N')
end if
这将允许您将表格与@emailOptions合并
from d_user_memb d1
left join m_user mu on d1.user_id = mu.user_id
left join m_memb_pledge mp on d1.memb_id = mp.memb_id
inner join @emailOptions on Option=@recvc_email
这允许您使用两个以上的选项,并且优化器将能够使用包含recv_email
的任何索引来创建更快的执行计划 线路
and (recv_email in (@recvemail ) )
相当于
and recv_email = @recvemail
中的用于仅传递一个参数的参数列表。它不会解析参数的内容以查看是否有任何参数可以解释为逗号分隔的列表
如果要对照选项列表进行检查,请创建一个表值参数,并在in
子句中使用它:
declare @emailoptions table (Option varchar(2))
IF (@recvemail = 'B' OR @recvemail = 'Y')
begin
insert into @emailoptions VALUES('Y')
end if
IF (@recvemail = 'B' OR @recvemail = 'N')
begin
insert into @emailoptions VALUES('N')
end if
这将允许您将表格与@emailOptions合并
from d_user_memb d1
left join m_user mu on d1.user_id = mu.user_id
left join m_memb_pledge mp on d1.memb_id = mp.memb_id
inner join @emailOptions on Option=@recvc_email
这允许您使用两个以上的选项,并且优化器将能够使用包含recv_email
的任何索引来创建更快的执行计划 你不能像那样在
中使用。这不是条款的工作原理<必须显式定义
中的code>,并且不能使用串联字符串的变量。不能像这样在中使用。这不是条款的工作原理<必须显式定义
中的code>,并且不能使用串联字符串的变量。我假定您的意思是recv\u email=case…
。这可能导致执行计划效率低下。优化器将缓存第一次执行产生的执行计划。如果这是一个B
,它将不考虑对recv\u电子邮件的过滤,例如忽略包含it@PanagiotisKanavos你说得对。我已经编辑了我的答案。谢谢@Zohar Peled的精彩回答。我按照你的建议改变了我的程序后把它修好了。你刚刚用一行代码解决了我的问题。非常感谢。我想你的意思是recv\u email=case…
。这可能导致执行计划效率低下。优化器将缓存第一次执行产生的执行计划。如果这是一个B
,它将不考虑对recv\u电子邮件的过滤,例如忽略包含it@PanagiotisKanavos你说得对。我已经编辑了我的答案。谢谢@Zohar Peled的精彩回答。我按照你的建议改变了我的程序后把它修好了。你刚刚用一行代码解决了我的问题。非常感谢。虽然我大体上同意表值参数方法,并在stackoverflow和其他网站上多次推荐它,但我认为在这一点上你是在用大象枪射击苍蝇。我无法想象有其他选择来回答“是”或“否”的问题……谢谢你的解决方案。我接受了@Zohar Peled作为我的答案,因为他的解决方案在一行中解决了我的问题。@Zohar取决于电话的频率。如果是偶尔,我同意。如果频繁出现,缺少索引将是一个问题pain@BSG不同的解决方案适用于不同的场景。偶尔备份一次可能不需要高性能。但频繁的群发邮件可以避免长时间阻塞用户表。您可能还可以在每个场景中使用不同的视图(我会),以简化存储过程procedure@PanagiotisKanavos请参阅我编辑的答案。在我建议的解决方案中,没有什么可以阻止数据库在recv_电子邮件上使用任何索引……虽然我通常同意表值参数方法,并在stackoverflow和其他网站上多次推荐它,但我认为你在这一点上是在用大象枪射击苍蝇。我不想有其他选择来回答“是”或“否”的问题……谢谢