【问题标题】:SQL Problem with IN keyword in stored procedure存储过程中 IN 关键字的 SQL 问题
【发布时间】:2021-08-10 01:18:33
【问题描述】:

下一行返回表中包含这些成分的所有 ID。

SELECT DISTINCT RecID 
FROM ingr 
WHERE Ingredient IN ('rice', 'salt', 'pepper')

但是,如果我将其放入存储过程中,它就不起作用了...

第一个问题是我无法传递 '(撇号),所以我不得不使用另一个字符,这就是我替换它的原因。

DECLARE @IngList nvarchar(255)
SET @IngList = replace('(|rice|,|salt|,|pepper|)','|','''')

-- select @inglist ->  Result: 'rice','salt','pepper'
SELECT DISTINCT RecID 
FROM ingr 
WHERE Ingredient IN (@IngList)

结果什么都不是——为什么?

【问题讨论】:

  • 嗯 - IN 运算符期望使用 值列表 - 但是,您只是提供一个简单的单个字符串(包含多个值 - 但是它仍然只是一个字符串)。根据您使用的 RDBMS - 您需要 某种方式 将作为参数传递的字符串分解为 IN 运算符的值列表 - 或更改存储过程以获得开始的基于列表的参数。但这完全非常依赖您使用的是什么具体的RDBMS - SQL 只是查询语言,它并没有告诉我们您使用的是什么,真的....
  • 我使用的是 MSSQL 最新版本。
  • 然后要么在你的字符串参数上使用STRING_SPLIT,要么签出table-valued parameters来传入多个值(适合IN
  • 显然不够聪明,无法弄清楚,所以我将创建一个动态查询...

标签: sql sql-server csv tsql search


【解决方案1】:

最好使用表变量、临时表或表值参数。这样,您正在执行一个完全基于集合的操作

DECLARE @IngList TABLE (Ingredient nvarchar(255) NOT NULL);

INSERT @IngList (Ingredient)
VALUES ('rice'), ('salt'), ('pepper');

SELECT DISTINCT RecID 
FROM ingr 
WHERE Ingredient IN (SELECT t.Ingredient FROM @IngList t)

【讨论】:

    【解决方案2】:

    如果字符串中有分隔的值列表,则可以使用string_split 将它们提取为派生表。然后你可以加入它,或与in一起使用它

    以下两者基本相同:

    select distinct RecID 
    from ingr 
    where Ingredient in (select value from String_Split(@IngList,','))
    
    select distinct RecID 
    from ingr 
    cross apply String_Split(@IngList,',')s 
    where ingredient=s.value
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多