2012-12-05 2 views
1

Я получаю следующее сообщение об ошибке в SQL Server:T-SQL ERROR - подзапрос возвращает более чем на 1 значение

Msg 512, уровень 16, состояние 1, строка 18 Subquery возвращается более чем на 1 значения. Это недопустимо, когда подзапрос следует =,! =, <, < =,>>,> = или когда подзапрос используется как выражение.

Мой код выглядит следующим образом:

DECLARE 
@personNumber varchar(20), 
@itemNumber varchar(20) 


SET @personNumber = 'null' 
SET @itemNumber = 'null' 

SELECT  
    OU.UserID 
    ,OU.Name 
    ,IGWQ.itemNumber 
    ,IG.itemName 
    ,IGWQ.QuantityOnHand 
FROM dbo.Table1 IGWQ 
INNER JOIN Table2 OU  ON IGWQ.UserId = OU.UserId 
INNER JOIN Table3 IG  ON IGWQ.itemNumber = IG.itemNumber 
WHERE IGWQ.userid IN (CASE WHEN @personNumber = 'null' 
          THEN ( SELECT DISTINCT 
             UserID 
            FROM Table2 WITH(NOLOCK) 
            WHERE [Role] = '01') 
          ELSE @personNumber 
          END) 
AND IGWQ.itemNumber IN (CASE WHEN @itemNumber = 'null' 
           THEN ( SELECT DISTINCT 
              itemNumber 
             FROM dbo.Table1 WITH(NOLOCK)) 
           ELSE @itemNumber 
           END) 

Может кто-нибудь предложить решение этой проблемы? Я думал, что использование «IN» решило бы проблему.

+0

Вы находитесь на правильном пути, но ваш оператор CASE не может вернуть несколько значений. – cairnz

ответ

2

использовать это, чтобы исправить все остальное:

WHERE ((@personNumber <> 'null' AND @personNumber = IGWQ.userid) 
OR (@personNumber = 'null' AND IGWQ.userid IN ( SELECT UserID 
            FROM Table2 WITH(NOLOCK) 
            WHERE [Role] = '01') 
    )) 

Вам не нужно неповторяющиеся как оператор IN обрабатывает только различные значения.

+0

спасибо, это работает! –

+0

У меня была эта проблема при использовании ГДЕ ... CASE ... Выберите, переключил CASE на OR и решил это так. – Brent

0
WHERE (IGWQ.userid = @personNumber OR 
     @personNumber = 'NULL' and 
     EXISTS (SELECT * 
       FROM Table2 t WITH (NOLOCK) 
       WHERE t.[Role] = '01' AND t.UserID = IGWQ.userid) 
) 
    AND (IGWQ.itemNumber = @itemNumber OR 
     @itemNumber = 'NULL' and 
     EXISTS (SELECT * 
       FROM dbo.Table1 t WITH (NOLOCK) 
       WHERE t.itemNumber = IGWQ.itemNumber) 
) 

Примечание:

  1. СЛУЧАЯ возвращает скаляр, он не может возвращать подзапрос (то есть набор).
  2. WITH (NOLOCK) устарел. измените изоляцию соединения вместо READ UNCOMMITTED или SNAPSHOT.
+0

Также этот не делает ту же логику. Если '@personNumber <> null', вы должны проверить' @personNumber = IGWQ.userid' - ваша версия этого не делает. – cairnz

+0

спасибо за ваш вклад RichardTheKiwi. –

Смежные вопросы