При выполнении длинных скриптов в MSSQL-студии хочется наблюдать статус. Куда дошло, что происходит в данный момент, сколько осталось? Для этого можно использовать оператор PRINT Но у него есть одна крайне неприятная особенность. Выводит текст только когда уже скрипт выполнен. Частный случай: при выполнении команды GO, что по сути - то же самое. То есть чтобы сразу увидеть текст - можно после PRINT вставить GO, и мгновенно увидим сообщение. Но минус данного финта состоит в том, что при выполнении GO мы какбы намекает SQL что предыдущая часть скрипта уже отработала полностью, и он удаляет все перемененные, определённые через DECLARE, а это в некоторых случаях заставляет пренебречь выводом сообщений в пользу сохранения работоспособности скрипта.
Но выход есть, конструкция RAISERROR (и не спрашивайте, где еще одна Е ) С флагом WITH NOWAIT Чуть сложней использовать из-за того, что текст сообщения нельзя собирать динамически при передаче в метод, но в целом даёт нужный результат
Иногда возникает желание посмотреть что именно сейчас делается в SQL: какие запросы выполняются и какие транзакции активны?
Сделать это можно следующим образом.
Текущие запросы, с их текстами
select session_id, status, wait_type, command, last_wait_type
, qt.text sql_text
, total_elapsed_time/1000 as [total_elapsed_time, sec],
wait_time/1000 as [wait_time, sec], (total_elapsed_time - wait_time)/1000 as [work_time, sec] , percent_complete
from sys.dm_exec_requests as qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
where session_id >= 50 and session_id <> @@spid -- чтоб исключить текущую сессию и этот запрос
Самая долгая транзакция
DBCC OPENTRAN
Возвращает результаты в виде Oldest active transaction: SPID (server process ID): 65 UID (user ID) : -1 Name : user_transaction LSN : (14627553:1424:2) Start time : Mar 12 2018 5:25:34:807PM SID : 0x01
Подробности транзакции по SPID
DECLARE @sqltext VARBINARY(128)
SELECT @sqltext = sql_handle
FROM sys.sysprocesses
WHERE spid = [SPID, полученный из DBCC OPENTRAN]
SELECT *
FROM sys.dm_exec_sql_text(@sqltext)
GO
Принудительно откатить транзакцию, можно убив процесс
На практике MSSQL DBA бывают случаи, когда необходимо прикрепить базу SQL и журнала транзакций нет. ЛИБО лог очень вырос и никакой shrink не помогает уменьшить его размер (модель восстановления simple) В этом случае, после закрытия всех транзакций, можно сделать Detach базы После чего переместить-переименовать файл журнала транзакций, и attach-нуть базу следующим скриптом
Если всё хорошо - получим сообщение вида File activation failure. The physical file name "D:\path\db_log.ldf" may be incorrect. New log file 'D:\path\db_log.LDF' was created. SQL создаст пустой журнал транзакций на старом месте. После чего старый лог можно удалить.
Данный способ не сработает, если в базе на момент отключения были неподтвержденные транзакции. В этом случае поможет план Б из статьи https://infostart.ru/public/277252/