尝试使用子查询作为表达式,需要替代方案/帮助

时间:2011-07-05 14:31:08

标签: sql-server-2005 tsql subquery expression

SQL Server 2005。

我有一个存储过程,它接受一些可能会或可能不会传递数据的参数。所以他们可能会以空字符串形式出现,或者他们可能会收到数据。

数据将是ID的分隔列表...制造商ID,目录ID等.proc搜索记录,如果这些参数中的任何一个具有数据,则在where子句中使用它。

FYI:Split是一个拆分字符串(接受分隔符)并返回表格的函数。


WHERE

...

AND m.Mfg_ID in (CASE WHEN @manufacturerIds <> '' THEN (SELECT * FROM Split(@manufacturerIds, '|')) ELSE (select m.Mfg_Id) END)

我收到错误: “子查询返回的值超过1。当子查询跟随=,!=,&lt;,&lt; =,&gt;,&gt; =或子查询用作表达式时,不允许这样做。”

我不明白的是,如果我删除CASE声明,那么我就是这样......


WHERE

...

AND m.Mfg_ID in (SELECT * FROM Split(@manufacturerIds, '|'))

......它运行正常;但是,这使我无法传递空字符串。

非常感谢任何帮助!

4 个答案:

答案 0 :(得分:2)

区别在于(select m.Mfg_Id)返回单行,但(select * from split(...))返回多行。 case会返回单个值,因此它不知道如何处理来自Split的多行。

而不是case你可以将它们结合在一起:

and m.Mfg_ID in 
(
select  *
from    Split(@manufacturerIds, '|')
where   @manufacturerIds <> ''
union all
select  m.Mfg_Id
where   @manufacturerIds = ''
)

union的下半部分仅在@manufacturerIds = ''时运行。

答案 1 :(得分:1)

SELECT m.Mfg_ID -- , other columns
    FROM dbo.base_table_name AS m
    LEFT OUTER JOIN dbo.Split(@ManufacturerIds) AS f
    ON (m.Mfg_id = f.column_name)
    WHERE @manufacturerIds = '' 
    OR f.column_name IS NOT NULL;

答案 2 :(得分:0)

我认为这可能与CASE子查询的'SELECT *'部分有关。请尝试仅选择一列。

答案 3 :(得分:0)

我试图将你的“where”子句重写为对我来说更符合逻辑的东西。我没有将文本拆分成较小的位,而是将文本与“LIKE”进行比较。我认为这会带来更好的表现。

DECLARE @t table (Mfg_id VARCHAR(10))
DECLARE @manufacturerIds VARCHAR(50)
INSERT @t 
SELECT 'aaa' UNION ALL SELECT 'a' UNION ALL SELECT 'ab' UNION ALL SELECT 'abc'

SET @manufacturerIds = '|' +'aaa|abc|bbb' + '|'

SELECT Mfg_ID matching FROM @t m
WHERE ( @manufacturerIds like '%|' + CAST(m.Mfg_ID AS VARCHAR(20)) + '|%' OR @manufacturerIds = '')

结果:

matching
----------
aaa
abc

如果您只想在此处更正您的正确脚本,请执行以下操作:

AND (@manufacturerIds = '' or m.Mfg_ID in (SELECT * FROM Split(@manufacturerIds, '|')))