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, '|'))
......它运行正常;但是,这使我无法传递空字符串。
非常感谢任何帮助!
答案 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, '|')))