SP возвращает ноль как НОЛЬ? - PullRequest
3 голосов
/ 21 августа 2009

Используя хранимую процедуру, у меня есть довольно сложный оператор SQL, который возвращает значение COUNT в виде псевдостолбца. Во многих случаях результат будет нулевым. Это вызывает проблемы в моем приложении, поэтому мне интересно, возможно ли вернуть 'null' как '0' по умолчанию из хранимой процедуры?

Спасибо.

UPDATE

Мне нужно применить ISNULL к следующему утверждению;

    select recip_Chosen, recip_CampaignId) AS ChosenCount
    from TBL_CAMPAIGNRECIPIENTS
    WHERE recip_CampaignId =  @campaign
    group by recip_Chosen

Что должно быть что-то вроде;

    select recip_Chosen, ISNULL(count(recip_CampaignId),0) AS ChosenCount
    from TBL_CAMPAIGNRECIPIENTS
    WHERE recip_CampaignId =  @campaign
    group by recip_Chosen

Однако, это все еще возвращает ноль (и) в столбце ChosenCount. Есть идеи?

UPDATE

Хорошо, поэтому приведенное выше утверждение является частью гораздо большего, как показано ниже. Здесь представлена ​​полная хранимая процедура, но не структура таблицы, поскольку она включает несколько таблиц. Мне нужно только 'ChosenCount', чтобы вернуть '0' вместо Null. SP действительно возвращает 1 строку для каждой записи в TBL_CAMPAIGNS_CHARITIES, где это соответствует TBL_CAMPAIGNS.

CREATE PROCEDURE web.getPublicCampaignData
   (
   @campaign BIGINT
   )
AS
BEGIN

SELECT * 
FROM TBL_CAMPAIGNS C
INNER JOIN TBL_MEMBERS M
    ON C.campaign_MemberId = M.members_Id
INNER JOIN TBL_CAMPAIGNS_CHARITIES CC
    ON C.campaign_Key = CC.camchar_CampaignID
INNER JOIN TBL_CHARITIES CH
    ON CC.camchar_CharityID = CH.cha_Key
LEFT OUTER JOIN (
    select recip_Chosen, count(recip_CampaignId) as ChosenCount
    from TBL_CAMPAIGNRECIPIENTS
    WHERE recip_CampaignId =  @campaign
    group by recip_Chosen
) CRC
on CH.cha_Key = CRC.recip_Chosen
WHERE C.campaign_Key = @campaign;

END

Ответы [ 4 ]

10 голосов
/ 21 августа 2009

Да

RETURN ISNULL(yourvalue, 0)

Что это в основном означает:

  • , если "yourvalue" (или вычисленное значение, или значение @variable) не равно NULL, тогда вернуть это значение

  • если значение "yourvalue" равно NULL, вместо этого вернуть второй параметр (здесь "0")

Я не знаю точно, как вы вычислили свой счет - я предполагаю, что вы присваиваете его некоторой локальной переменной в вашей хранимой процедуре:

CREATE PROCEDURE dbo.DoMyCount()
RETURNS INT
AS BEGIN
   DECLARE @MyCountVariable INT

   SET @MyCountVariable = SELECT COUNT(*)......... -- whatever you do here

   RETURN ISNULL(@MyCountVariable, 0)
END

В этом случае ваша хранимая процедура dbo.DoMyCount вернет счетчик (как бы вы его не вычисляли), или «0» (ноль) означает, что счетчик равен NULL.

Таким образом, вы всегда можете получить верное значение NON-NULL INT из хранимой процедуры.

Марк

ОБНОВЛЕНИЕ:

Хранимая процедура проясняет, почему ISNULL не работает - он используется внутри левого внешнего соединения. Если никакие данные не совпадают, тогда весь выбор внутри LEFT OUTER JOIN никогда не будет вызван -> ISNULL никогда не получит шанса выполнить свою работу.

Вам нужно немного реструктурировать свой хранимый процесс:

CREATE PROCEDURE web.getPublicCampaignData(@campaign BIGINT)
AS BEGIN
  SELECT
     (list of fields), ISNULL(CRC.ChosenCount, 0), .....
  FROM TBL_CAMPAIGNS C
  INNER JOIN TBL_MEMBERS M 
     ON C.campaign_MemberId = M.members_Id
  INNER JOIN TBL_CAMPAIGNS_CHARITIES CC 
     ON C.campaign_Key = CC.camchar_CampaignID
  INNER JOIN TBL_CHARITIES CH 
    ON CC.camchar_CharityID = CH.cha_Key
  LEFT OUTER JOIN (
    select recip_Chosen, count(recip_CampaignId) as ChosenCount
    from TBL_CAMPAIGNRECIPIENTS
    WHERE recip_CampaignId =  @campaign
    group by recip_Chosen
  ) CRC on CH.cha_Key = CRC.recip_Chosen
  WHERE 
     C.campaign_Key = @campaign;
END

Таким образом, если CH.cha_Key = CRC.recip_Chosen не совпадает и LEFT OUTER JOIN возвращает NULL, оно будет перехвачено, а ChosenCount = NULL будет преобразовано в «0».

5 голосов
/ 21 августа 2009

Помимо isnull на SQL Server, я большой поклонник coalesce, так как это принимает любое количество аргументов. Для двух аргументов это функционально эквивалентно isnull:

return coalesce(yourvalue, 0)

То же, что и:

return isnull(yourvalue, 0)

Однако,

coalesce(yourvalue, backupval, 0)

эквивалентно

isnull(isnull(yourvalue, backupval), 0)

Очевидно, что coalesce гораздо более читабельно в этом случае, поэтому я фанат.

Извиняюсь за многословный ответ на очень простой вопрос, но эй, почему бы не узнать что-то еще, а?

2 голосов
/ 21 августа 2009

ISNULL, возможно, быстрее, но это специфично для SQLServer.

COALESCE - это стандарт ANSI

Вот некоторые различия и другие объяснения относительно ISNULL и COALESCE

2 голосов
/ 21 августа 2009
select isnull(sum(size),0) as total_size from my_table where is_valid = 1
...