我已经创建了一个用户定义的类型,叫做 membertypes
其中有一列类型为 int
叫做 membertype
,
我有一个存储过程是这样的。
declare @membertypes dbo.MemberTypes;
INSERT INTO @membertypes VALUES (1);
INSERT INTO @membertypes VALUES (3);
declare @membertypecount int = (select count(1) from @membertypes)
select username, MiniThumbNail, userID,
from members
where members.membertype in (case when @membertypecount > 0 then (select membertype from @membertypes) else members.membertype end)
它不工作,我得到错误信息:
子查询返回了超过1个值。当子查询跟随=, !=, <, <= , >, >=或者当子查询被用作表达式时,这是不允许的。
然而,如果我把代码改成这样,它确实可以工作:------为什么原来的代码会产生这种错误?
declare @membertypes dbo.MemberTypes;
INSERT INTO @membertypes VALUES (1);
INSERT INTO @membertypes VALUES (3);
select username, MiniThumbNail, userID,
from members
where members.membertype in (select membertype from @membertypes)
为什么原来的代码会产生这个错误?
这是你的逻辑。
where members.membertype in (case when @membertypecount > 0
then (select membertype from @membertypes)
else members.membertype
end)
你误解了... case
的表达方式是。 A case
表达式是一个返回单个标量值的表达式。 一个 "标量 "值有一个简单的类型,如整数或字符串。 (一些数据库将其扩展为包括元组和数组,但SQL Server不是其中之一)。 表达式的其他例子是算术('1 + 1'
)、函数(len('abc')
),甚至是简单的列。
子查询并不简单。
令人高兴的是,你想做的事情很容易,而不需要用到 case
:
where members.membertype in (select membertype from @membertypes) or
not exists (select 1 from @membertypes)
case
表达式只会返回一个单行的值,而子查询可能有多行。所以,case表达式无法使用
所以,您可以使用 left join
而不是:
select username, MiniThumbNail, userID
from members mb left join
@membertypes mt
on mt.membertype = mb.membertype
where (@membertypecount = 0 or mt.membertype is not null);
为什么原代码会产生该错误?
这是无效的。
case when @membertypecount > 0 then (select membertype from @membertypes) else members.membertype end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在一个 CASE WHEN x THEN y
的 y
必须代表一个单值,如 1
, 'apple'
等。在几组数据中选择其中一组送入IN中,有一个CASE WHEN是无效的。