Ваш исходный запрос имеет несколько лишних предикатов. Любое собрание строк LAST_NM_1 = LAST_NM_2
гарантированно будет иметь, например, LAST_NM_1 NOT NULL
и LAST_NM_2 NOT NULL
.
Но это можно сделать довольно кратко, используя VALUES
, чтобы получить 4 столбца в табличной форме, как показано ниже.
SELECT *
FROM LAST_NM
WHERE EXISTS (SELECT *
FROM (VALUES(LAST_NM_1),
(LAST_NM_2),
(LAST_NM_3),
(LAST_NM_4)) V(LAST_NM_N)
HAVING MAX(LAST_NM_N) = MIN(LAST_NM_N) /*exactly one NOT NULL value among the 4 columns*/
AND MAX(LAST_NM_N) <> LAST_NM_ORIGINAL)
Почему бы не цикл, где клиент просто проверяет с помощью ping-запросов сервис каждую приблизительно секунду и затем делает обратный вызов. когда обратный вызов перестал работать затем, клиент разъединился.
Вариация на опрос должна была бы использовать обмен сообщениями. Клиент мог отправить, "я здесь", передают и затем удаляют сообщение, когда оно разъединяется. Сервер мог контролировать очередь для разъединений. Другая опция состоит в том, чтобы использовать ЕРУНДУ, двунаправленную Связь HTTP. Это - то, что используют клиенты веб-чата.
Используйте события OperationContext.current.Channel.Faulted и OperationContext.current.Channel.Closed.
Эти события запускаются, когда клиент отсоединился по какой-либо причине.
.Я бы сказал, что если клиент отключается ненормальным способом, то нет никакой возможности убедиться, что сервер будет знать об этом. Это похоже на HTTP. Если мы закроем браузер, скажем, с принудительным выходом, браузер ничего не отправит на сервер.
Это одна из многих причин, почему у нас тайм-аут сессии. Чтобы отключить клиента и очистить на стороне сервера все, что используется, если клиент делает что-то не так (например, слишком длинные операции) или отключается, не сообщив об этом серверу.