我正在使用SQL SERVER 2008管理工作室
我有一个存储过程,它接受几个参数
一个参数名称为@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
我尝试使用这样的值执行该过程,但我没有得到任何输出
use CHTLIVE
GO
exec proc_getMembershipEmailbackup @From=N'1800-06-11',@To=N'2099-06-14',@DevoteeName=N'',@log_cond='', @recvemail='B'
如果将参数值@recvemail
从'B'
更改为'Y'
,我将正确输出,并且所有选择了电子邮件的用户都会在输出中正确显示。
同样,我将值从'B'
更改为'N'
我正确获取输出,并且所有未选择电子邮件的用户都会显示在输出中。
仅用于值'B'
我没有获得输出。我应该得到输出,以便所有选择或不选择电子邮件的用户都应该出现在输出中。
答案 0 :(得分:2)
正如Mark Sinkinson在his comment中写的那样,IN()
运算符需要逗号分隔的参数列表,但是您为它提供了一个包含逗号分隔值列表的参数。
更改存储过程的这一部分:
and (recv_email in (@recvemail ) )
到此:
and (recv_email = @recvemail OR @recvemail = 'B')
答案 1 :(得分:2)
该行
and (recv_email in (@recvemail ) )
相当于
and recv_email = @recvemail
IN
适用于只传递单个参数的参数列表。它不解析参数的内容,以查看它们中的任何一个是否可以解释为以逗号分隔的列表。
如果要检查选项列表,请创建一个表值参数并在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
的任何索引来创建更快的执行计划。