2016-09-05 3 views
0

При выполнении следующей процедуры:Почему я получаю результат, состоящий из более чем одной ошибки строки, когда, наконец, возвращается одна строка?

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `portaldb`.`is_optional_type_assigned`$$ 

CREATE DEFINER=`root`@`localhost` PROCEDURE `is_optional_type_assigned`(userId int, optionalPlanId int) 
begin 
     if userId is not null and optionalPlanId is not null then 
      // Will return multiple rows 
      select conv.FeatureName from planallocation as pa 
      left join subscriptioninfo as si 
      on si.SubscriptionId = pa.SubscriptionId 
      left join plans as pl 
      on pl.PlanId = pa.CurrentPlanId 
      right join conversiontable as conv 
      on conv.ConversionId = pl.OptionalFeatureId 
      where si.UserId = userId and 
      conv.FeatureType = 'optional' into @featureList; 

      // Will return single row 
      select conv.FeatureName from conversiontable as conv 
      right join plans as pl 
      on conv.ConversionId = pl.OptionalFeatureId   
      where conv.FeatureType = 'optional' and 
      pl.PlanId = optionalPlanId into @featureName; 

      if @featureName in (@featureList) then 
       select true as isAssigned; 
      else 
       select false as isAssigned; 
      end if; 
     end if; 
    end$$ 

DELIMITER ; 

Я получаю:

Error Code : 1172 
Result consisted of more than one row 

ошибку. Что может быть причиной этого? Результат от первого двух операторов select присваивается переменной, а затем сравнивается, если один набор содержит другой.

ответ

2

Вы получаете ошибку, потому что MySQL требует, чтобы запрос, выбранный в переменную, возвращал ровно одну строку - возврат нуля или более одной строки приводит к ошибке. Таким образом, ваш первый запрос, который вы комментируете, возвращает несколько строк, вызовет ошибку.

http://dev.mysql.com/doc/refman/5.7/en/select-into.html

вы могли бы изменить запрос на что-то вроде:

select GROUP_CONCAT(conv.FeatureName) from ..... 

, чтобы получить один список разделенных запятыми результат & затем искать @featureName в этом списке - но это может зависеть от количество возвращенных результатов. В противном случае вам необходимо перестроить свои два запроса - возможно, что-то вроде этого (обратите внимание, я включил предложение Гордона по параметру наименования):

/ Will return single row 
select conv.FeatureName from conversiontable as conv 
right join plans as pl 
on conv.ConversionId = pl.OptionalFeatureId   
where conv.FeatureType = 'optional' and 
pl.PlanId = in_optionalPlanId into @featureName; 

select IF(count(conv.FeatureName)>0,true,false) from planallocation as pa 
left join subscriptioninfo as si 
on si.SubscriptionId = pa.SubscriptionId 
left join plans as pl 
on pl.PlanId = pa.CurrentPlanId 
right join conversiontable as conv 
on conv.ConversionId = pl.OptionalFeatureId 
where si.UserId = in_userId and 
conv.FeatureType = 'optional' and 
conv.FeatureName = @featureName; 

Возможно реорганизовать его в более эффективный запрос или даже одного запроса.

+0

Будет 'если @ featureName in (@featureList) 'работает? На данный момент он не работает. –

+0

Если реорганизация, которую я предложил, работает - второй запрос приводит к результату true/false, поэтому «if @featureName in (@featureList)» не требуется. – PaulF

1

Ваш код не работает так, как вы думаете. Кардинальное правило при использовании параметров: Назовите их по-разному, поэтому они очевидны в коде.

Когда вы пишете:

where si.UserId = userId and 

Это интерпретируется как:

where si.UserId = si.userId and 

Я хотел бы предложить вам начать с более читаемым и полезным:

DELIMITER $$ 

DROP PROCEDURE IF EXISTS portaldb.is_optional_type_assigned$$ 

CREATE DEFINER = [email protected] PROCEDURE is_optional_type_assigned (
    in_userId int, 
    in_optionalPlanId int 
) 
BEGIN 
    if in_userId is not null and in_optionalPlanId is not null then 
     . . . 
END;$$ 

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