子查询返回的值超过1。子查询遵循=,!=,

时间:2015-09-30 21:24:53

标签: sql sql-server

我正在尝试从参数中读取多个值,将其存储在变量中,然后在select语句中使用它来提取多个值。

declare @codes XML = N'<Root>
                          <List Value="120" />
                          <List Value="110" />
                         </Root>';

declare @codeList VARCHAR(MAX) = (SELECT T.Item.value('@Value[1]','VARCHAR(MAX)')  FROM  @codes.nodes('/Root/List') AS T(Item));

WITH CODE_RESULT AS(      
       SELECT  ID, Name, Region,
                 FROM dbo.MyTable1    
                 WHERE
                 (@codes IS NULL OR DataCode IN ( @codeList))

       ...

       UNION

       SELECT  ID, Name, Region,
                 FROM dbo.MyTable2    
                 WHERE
                 (@codes IS NULL OR DataCode IN ( @codeList))

       ...

但是,我得到以下例外:

  

子查询返回的值超过1。这是不允许的   子查询跟随=,!=,&lt;,&lt; =,&gt;,&gt; =或当子查询用作   表达。

期望:

如何将参数值存储在变量中,然后在“in”子句下的多个select语句中重用它?任何建议都表示赞赏。

3 个答案:

答案 0 :(得分:5)

如果您需要存储多个值以供日后使用,请使用TABLE VARIABLE保存结果,如下所示:

DECLARE @dataCodes TABLE (DataCode varchar(MAX));
INSERT INTO @dataCodes
    SELECT T.Item.value('@Value[1]', 'varchar(max)')
      FROM @codes.nodes('/Root/List') AS T(Item);

然后,您可以使用“WHERE DataCode IN (SELECT DataCode FROM @dataCodes)”进行选择并获取所有结果。

答案 1 :(得分:3)

你的问题在这里:

declare @codeList VARCHAR(MAX) = (SELECT T.Item.value('@Value[1]','VARCHAR(MAX)')  FROM  @codes.nodes('/Root/List') AS T(Item));

您的select会返回两个结果(120,110),但标量VARCHAR变量只能保存一个。

您可以通过创建表变量来修复它:

DECLARE @codeList TABLE (code varchar(100));
INSERT @codeList 
SELECT  
  T.Item.value('@Value[1]','VARCHAR(MAX)')  
FROM  @codes.nodes('/Root/List') AS T(Item);

然后将(@codes IS NULL OR DataCode IN ( @codeList))更改为(@codes IS NULL OR DataCode IN (SELECT code FROM @codeList))

此处,LEFT JOIN的效果应优于当前语法,例如

WITH CODE_RESULT AS(      
  SELECT  ID, Name, Region,
  FROM dbo.MyTable1  t1 
  LEFT JOIN @codeList  cl
  ON t1.DataCode = cl.code

您可能需要添加其他逻辑来检查cl.code is null是否取决于您的意图。

答案 2 :(得分:3)

您创建一个表变量

<强> SQL Fiddle Demo

Declare @T_variable table(name varchar(200));

insert into @T_variable 
SELECT ID FROM Table1;

SELECT *
FROM YourTable
WHERE ID NOT IN
   (SELECT *
    FROM @T_variable)
;

GO