2012-06-29 3 views
-1

Привет Я пытаюсь выполнить запрос, чтобы получить строку между определенным числом, Как я пытаюсь получить строки между 10-20. поэтому я использую подзапрос так, что я могу использовать row_number() функциюSQL-подзапрос возвращает больше, что 1 значение

запрос не выполняется с ошибкой:

SQL subquery return more that 1 value

Так мне нужно найти способ, потому что мне нужно, чтобы получить больше, что 1 resulset из ряда запрос

PROCEDURE dbo.Search 

    (
    @search_text varchar(max), 
    @search_category varchar(max), 
    @page int, 
    @COUNT INT OUTPUT 
    ) 

AS 

    SET NOCOUNT ON 
    DECLARE @Lower_limit int = (@page-1)*10; 
    DECLARE @Upper_limit int = (@page * 10) + 1; 
    -- SET @COUNT =0 
    IF @search_category='deal' 
    BEGIN 
     SET @COUNT = (SELECT COUNT(*) FROM dealData WHERE dealInfo LIKE '%' + @search_text + '%' OR dealName LIKE '%' + @search_text + '%' OR dealDescription LIKE '%' + @search_text + '%' GROUP BY dealId); 
     SELECT x.dealId , x.ROW 
     FROM 
     (SELECT dealId,ROW_NUMBER() OVER(ORDER BY dealId) as ROW from dealData WHERE dealInfo LIKE '%' + @search_text + '%' OR dealName LIKE '%' + @search_text + '%' OR dealDescription LIKE '%' + @search_text + '%' GROUP BY dealId)x 
     WHERE x.ROW < @Upper_limit AND x.ROW > @Lower_limit 
    END 

Это полная процедура, и когда я пытаюсь вызвать его из следующего кода я получаю исключение при _command.ExecuteReader(); Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

_query = "Search"; 
       _command = new SqlCommand(_query, _connection); 
       _command.CommandType = CommandType.StoredProcedure; 
       _command.Parameters.AddWithValue("@search_text", search_text); 
       _command.Parameters.AddWithValue("@search_category", search_category); 
       _command.Parameters.AddWithValue("@page", page); 
       var returnParameter = _command.Parameters.Add("@COUNT", SqlDbType.Int); 
       returnParameter.Direction = ParameterDirection.Output; 
       _reader = _command.ExecuteReader(); 
       while (_reader.Read()) 
       { 
        search_result index = new search_result(); 
        index.category_id = this._categoryIdFromName(search_category); 
        index.post_id = _reader.GetValue(0).ToString(); 
        _searchList.Add(index); 
       } 
+2

Вы уверены, что это все ваши SQL и что выше SQL завершается с ошибкой вы сказали? Если нет, напишите фактический SQL, который возвращает сообщение об ошибке –

+0

Что такое * проблема *? Что вы получаете, и чего вы хотите получить? Пока все выглядит правильно. –

+0

Когда я пытаюсь запустить эту процедуру, я получаю это исключение. Подзапрос возвращает более 1 значения. Это недопустимо, когда подзапрос следует за =,! =, <, <= , >,> = или когда подзапрос используется как выражение. «Но когда я выполняю процедуру с одинаковыми параметрами из студия управления sql, я получаю ожидаемый результат – Amrit

ответ

4

Проблема эта часть вашего зр:

SET @COUNT = ( SELECT COUNT(*) FROM dealData 
       WHERE dealInfo LIKE '%' + @search_text + '%' 
       OR dealName LIKE '%' + @search_text + '%' 
       OR dealDescription LIKE '%' + @search_text + '%' 
       GROUP BY dealId) 

В частности, GROUP BY dealId часть. Если в этой таблице есть несколько dealId, вы получите несколько строк в результате. Очевидно, вы не можете назначить это для скалярной переменной. Либо @Count нужно будет объявить как переменную таблицы (которая изменит логику остальной части вашего sp), либо вы избавитесь от GROUP BY dealId и убедитесь, что она дает вам желаемые результаты.

+0

Идентификатор группы является первичным ключом, так что не следует считать уникальным результат – Amrit

+0

@Amrit - Вы, кажется, не понимаете проблему. Если 'dealId' является основным ключом, то его проще объяснить.Если условия, которые вы положили на 'WHERE', возвращают более одной строки (предположим, что она возвращает 3 строки), тогда, поскольку вы группируете первичный ключ, у вас будет 3 строки со значением count 1 вместо 1 строки со значением счета 3. И, конечно, результат, который вы получаете, не может быть привязан к скалярной переменной. – Lamak

+1

Группа вернется ... DealID = 1, Count = 3 | DealID = 2, Count = 2 | DealID = 3, Count = 5 ... и т. Д. – Charleh

2

Я должен согласиться с @Lamak, и я только отправляю ответ, чтобы повторение могло нанести знание. Если вы повторно написать задание следующим образом, ваша проблема исчезнет:

SELECT @COUNT = COUNT(*) 
    FROM dbo.dealData 
    WHERE dealInfo  LIKE '%' + @search_text + '%' 
    OR dealName  LIKE '%' + @search_text + '%' 
    OR dealDescription LIKE '%' + @search_text + '%' 
    /* GROUP BY dealId */ -- there is NO REASON for this grouping if you want total count! 
; 
0

Кроме того, что все остальные заявили о вложенном запросе, который заполняет переменные возвращения нескольких строк, может быть более эффективным средством для получить то, что вы ищете (что я предполагаю, это подкачка). Это предполагает, что GroupId является первичным ключом DealData таблицы, как указано в комментариях:

Declare @Results Table 
    (
    DealId ... not null Primary Key 
    , RowNumAsc int not null 
    , TotalCount int not null 
    ); 

With NumberedData As 
     (
     Select DealId 
      , Row_Number() Over (Order By GroupId) As RowNumAsc 
      , Row_Number() Over (Order By GroupId Desc) As RowNumDesc 
     From DealData 
     Where dealInfo LIKE '%' + @search_text + '%' 
      Or dealName LIKE '%' + @search_text + '%' 
      Or dealDescription LIKE '%' + @search_text + '%' 
     ) 
Insert @Results(DealId, RowNumAsc, TotalCount) 
Select DealId, RowNumAsc 
    , Min(RowNumAsc + RowNumDesc - 1) As Count 
From NumberedData 
Where RowNumAsc < @UpperLimit 
    And RowNumAsc >= @LowerLimit 
Group By DealId 

Set @Count = (Select TOP 1 TotalCount From @Results); 
Select DealId, RowNumAsc 
From @Results 
Смежные вопросы