Фон :
Мы пытаемся создать AG "основной" тестовый комплект для одной из наших групп поддержки. Не зная, какие серверы в любой момент времени будут первичными, им было поручено выполнить TSQL для зарегистрированной группы серверов. Зарегистрированная группа серверов состоит из всех серверов в AG. Цель состоит в том, чтобы выполнить TSQL только на текущем основном сервере:
Текущий тестовый жгут :
IF EXISTS (SELECT *
FROM sys.dm_hadr_availability_replica_states AS HARS
INNER JOIN sys.dm_hadr_availability_replica_cluster_states AS HACS ON HACS.replica_id = HARS.replica_id
WHERE (HARS.role_desc = 'PRIMARY') AND (HACS.replica_server_name LIKE @@SERVERNAME))
BEGIN
<<SOME CODE TO EXECUTE>>
END
Проблема :
Если первый сервер, который отвечает обратно на многосерверный запрос, не возвращает никаких результатов, SSMS будет считать, что правильный набор результатов не является набором результатов, даже если другие серверы позже возвращаются с набором результатов. Таким образом, в этом случае результаты не возвращаются ... это неверно и не является ожидаемой функциональностью.
Может кто-нибудь придумать, как с помощью SSMS (это наиболее знакомый инструмент для команды CS) принудительно выполнять только на текущем основном сервере?
источник
Ответы:
Я сталкивался с этим ** раньше, и, если я правильно помню, чтобы всегда получать результаты с многосерверными запросами, вам нужно принудительно установить пустой набор результатов, если в противном случае строки не были бы возвращены. Это значит, что вам нужна
ELSE
ветка,IF
и внутриELSE
вы бы сделали что-то вроде следующего:Это приводит к пустому набору результатов с правильными именами и типами данных.
ИЛИ, и я не пробовал это в прошлом (просто подумал об этом, когда я набирал это), но вы могли бы сойти с рук с простой паузой в этой
ELSE
ветви, так что основной / предполагаемый сервер всегда может вернуть свой сначала набор результатов (что является настоящей проблемой: первый отвечающий сервер определяет структуру, которой должны придерживаться все остальные ответы). Следовательно, следующее может работать как единственное вELSE
:Но я не помню, чтобы другие серверы вообще ничего не возвращали, что вызвало сообщение об ошибке на вкладке «Сообщения». Если это произойдет, то пустой набор результатов определенно поможет. Но если это сработает, то это может работать лучше в общем шаблоне (как кажется в вашем случае), так как для этого не потребуется корректировать принудительный пустой набор результатов при каждом его использовании.
ОБНОВИТЬ:
ФП проверил, что:
WAITFOR DELAY
действительно работает, и** Ситуация, с которой я столкнулся, была похожей, но не имела ничего общего ни с группами доступности, ни с желанием получить результаты только с одного сервера. Наша ситуация состояла в том, что у нас было 18 серверов одной и той же схемы с разными данными, и нам нужно было выполнять различные задачи по обслуживанию, объединяя все 18 узлов. Существовали некоторые хранимые процедуры, которые по какой-то причине иногда не возвращали какой-либо набор результатов, и какова бы ни была эта причина, она не могла быть исправлена в хранимой процедуре. Таким образом, в зависимости от того, какой узел возвратился первым, большую часть времени все было в порядке, но время от времени узел, который иногда не возвращал набор результатов, возвращал первым. Итак, мне нужно было сделать что-то вроде вывода результатов во временную таблицу, и если бы
@@ROWCOUNT
этоINSERT...EXEC
было 0, я бы выбрал принудительный пустой набор результатов.источник
WAITFOR DELAY
подхода, и вы подтвердили, что он сработал, поэтому спасибо за это!Я всегда использовал временную таблицу для получения результатов, чтобы получить согласованные ответы от всех серверов в группе. Многосерверные запросы - одна из моих любимых вещей в SSMS.
источник