IN()子句中的子查询导致错误
时间:2020-03-06 15:02:11 来源:igfitidea点击:
我使用的是SQL Server 2005,但遇到错误,我敢肯定应该不会得到。
Msg 512, Level 16, State 1, Procedure spGetSavedSearchesByAdminUser, Line 8 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
我正在关注exampleB
此MSDN链接。
我存储的proc代码如下。如果我们要求的话,我可以为这篇文章简化它:
ALTER PROCEDURE [dbo].[spGetSavedSearchesByAdminUser] @strUserName varchar(50) ,@bitQuickSearch bit = 0 AS BEGIN SELECT [intSearchID] ,strSearchTypeCode ,[strSearchName] FROM [tblAdminSearches] WHERE strUserName = @strUserName AND strSearchTypeCode IN ( CASE @bitQuickSearch WHEN 1 THEN 'Quick' ELSE (SELECT strSearchTypeCode FROM tblAdvanceSearchTypes) END ) ORDER BY strSearchName END
我检查了子查询的结果集与与子查询结果进行比较的strSearchTypeCode之间是否没有数据类型不匹配。
我看不出为什么这行不通。如果我们有任何线索,请告诉我。
解决方案
我不知道我们可以在IN子句中使用CASE语句。我建议将其重写为:
WHERE strUserName = @strUserName AND ( (@bitQuickSearch = 1 AND strSearchTypeCode = 'Quick') OR (strSearchTypeCode IN (SELECT strSearchTypeCode FROM tblAdvanceSearchTypes)) )
或者,如果我们真的很喜欢那里的风格:
WHERE strUserName = @strUserName AND strSearchTypeCode IN ( SELECT CASE @bitQuickSearch WHEN 1 THEN 'Quick' ELSE strSearchTypeCode END FROM tblAdvanceSearchTypes )
通常,如果@bitQuickSearch = 1,则SQL应该足够聪明,足以优化表。但是,我只是为了确定(信任但要验证)检查查询计划。
在我看来,此SELECT:
SELECT strSearchTypeCode FROM tblAdvanceSearchTypes
返回多行,那是你的问题。我们可以将其重写为:
SELECT TOP 1 strSearchTypeCode FROM tblAdvanceSearchTypes
尝试重新排列查询,以便布尔表达式出现在子选择内部,例如
ALTER PROCEDURE [dbo].[spGetSavedSearchesByAdminUser] @strUserName varchar(50) ,@bitQuickSearch bit = 0 AS BEGIN SELECT [intSearchID] ,strSearchTypeCode ,[strSearchName] FROM [tblAdminSearches] WHERE strUserName = @strUserName AND strSearchTypeCode IN (SELECT strSearchTypeCode FROM tblAdvanceSearchTypes where @bitQuickSearch=0 UNION SELECT 'Quick' AS strSearchTypeCode WHERE @bitQuickSearch=1) ORDER BY strSearchName END