NullReferenceException с использованием COALESCE в запросе SQL

Возможно, я неправильно понимаю COALESCE, но, по сути, я пытаюсь выполнить запрос выбора, который, если он возвращает NULL вместо int, вместо этого возвращает 0 для целей ExecuteScalar ().

Запрос SQL Server:

SELECT TOP 1 COALESCE(SeqNo,0) 
FROM tblProjectChangeOrder 
WHERE ProjectID = XXXXX 
ORDER BY SeqNo DESC

Если предоставленный ProjectID существует в таблице Change Order, он возвращает ожидаемый наивысший SeqNo. Однако, если предоставленный ProjectID не имеет существующих заказов на изменение (таким образом, возвращает NULL для SeqNo), а не COALESCE, возвращающий 0, я все равно получаю NULL.

Я просто ошибаюсь в синтаксисе или все, что я хочу, возможно с COALESCE? Другой вариант, который я вижу, - это передать мой ExecuteScalar () обнуляемому int, а затем следовать за ним с помощью ?? чтобы объединиться в моем коде C#.

Возможно, вы захотите перечитать, что делает COALESCE. Если строк нет, почему вы ожидаете строк? COALESCE работает на уровне строк.

Llama 09.04.2018 17:44

Почему бы просто не обработать это на стороне клиента? Это идеальный кандидат на if (something==DBNull.Value) something=0;.

Alejandro 09.04.2018 17:51

@Sami, похоже, он выполняет ExecuteScalar на нулевых строках (проекта нет в таблице изменений)

Llama 09.04.2018 17:51

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

Kevbo 09.04.2018 17:51

Взгляните на этот вопрос: dba.stackexchange.com/questions/165295/…

McNets 09.04.2018 17:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
101
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Как Джон упомянул в комментариях, COALESCE работает на уровне строк. Если таблица не содержит строк или инструкция не возвращает строк, то строки не будут возвращены. Вот простой пример:

CREATE TABLE #Sample (ID int);

SELECT COALESCE(ID, 0)
FROM #Sample;

DROP TABLE #Sample;

Обратите внимание, что ничего не возвращается.

Вместо этого можно использовать подзапрос. По вашему запросу это приведет к следующему:

SELECT COALESCE(SELECT TOP 1 SeqNo 
                FROM tblProjectChangeOrder 
                WHERE ProjectID = XXXXX 
                ORDER BY SeqNo DESC),0) AS SeqNo;

Это также предполагает, что Seqno имеет тип данных int; в противном случае вы, вероятно, получите ошибку преобразования.

Хороший. Выберите max (SeqNo) будет немного короче.

paparazzo 09.04.2018 18:14

Не знал, что Select Max () был чем-то особенным. Делает это намного чище. SELECT COALESCE(( SELECT MAX(SeqNo) FROM tblProjectChangeOrder WHERE ProjectID = XXXXX),0) AS SeqNo

Jeff Cox 09.04.2018 18:58

ISNULL здесь лучше, чем COALESCE. COALESCE выполнит подзапрос дважды

Martin Smith 14.04.2018 23:18

Я предполагаю, что исключение нулевой ссылки возникает в коде и не имеет ничего общего с запросом sql. Возможно, ваш код не обрабатывает то, что вы не возвращаете строки (или скаляр в вашем случае), но вы можете пытаться получить к нему доступ где-то в C#.

Покажите нам строку кода, которая генерирует это исключение в C#, чтобы мы могли это подтвердить.

С уважением

Обновлено: из эта похожая тема

В своем коде на C# вы, возможно, захотите попробовать («cmd» - это ваш объект «SqlCommand»):

int result = 0;
int.TryParse(cmd.ExecuteScalar(), out result);

или в одну строку

int.TryParse(cmd.ExecuteScalar(), out int result);

Не знаю, подходит ли вам это решение, но надеюсь, что это начало.

Поскольку покрытые null и никакая строка - это не одно и то же. Этот образец покрывает это.

set nocount on;
select isnull(1, 0) 
where 1 = 1;
select isnull(1, 0) 
where 1 = 2;
select isnull(null, 0) 
where 1 = 1;
select isnull(null, 0) 
where 1 = 2;

-----------
1


-----------


-----------
0


-----------

это должно работать

select top 1 isnull(seq, 0) 
from (select null as seq 
      union all   
      select max(seq) from tblProjectChangeOrder where ProjectID = XXXXX 
     ) tt
order by seq desc

Другие вопросы по теме