logo
Фёдор Самородов  Преподаватель специального назначения
О проекте Просмотр Уровни подписки Фильтры Обновления проекта Контакты Поделиться Метки
Все проекты
О проекте
Учебные материалы по работе с данными и смежным темам для ИТ-специалистов.
Хранение, обработка и анализ данных на пределе возможностей.
Публикации, доступные бесплатно
Уровни подписки
Единоразовый платёж

Безвозмездное пожертвование без возможности возврата. Этот взнос не предоставляет доступ к закрытому контенту.

Помочь проекту
Уровень 1 500₽ месяц 5 100₽ год
(-15%)
При подписке на год для вас действует 15% скидка. 15% основная скидка и 0% доп. скидка за ваш уровень на проекте Фёдор Самородов

Доступ к платным материалам.

Оформить подписку
Фильтры
Обновления проекта
Контакты
Поделиться
Читать: 3+ мин
logo Фёдор Самородов

Как проверить принадлежность пользователя SQL Server к группе или к роли

Опытные ‎разработчики‏ ‎и ‎администраторы ‎прекрасно ‎знают, ‎что‏ ‎никогда ‎и‏ ‎ни‏ ‎при ‎каких ‎обстоятельствах‏ ‎нельзя ‎назначать‏ ‎разрешения ‎отдельным ‎пользователям. ‎Только‏ ‎группам‏ ‎или ‎ролям!

Это‏ ‎действительно ‎правильный‏ ‎подход, ‎но ‎если ‎вы ‎его‏ ‎исповедуете,‏ ‎время ‎от‏ ‎времени ‎у‏ ‎вас ‎будет ‎возникать ‎необходимость ‎проверять‏ ‎членство‏ ‎конкретного‏ ‎пользователя ‎(как‏ ‎правило, ‎текущего)‏ ‎к ‎той‏ ‎или‏ ‎иной ‎группе‏ ‎или ‎его ‎принадлежность ‎к ‎конкретной‏ ‎роли.

В ‎SQL-сервере‏ ‎есть‏ ‎простые ‎функции ‎и‏ ‎представления ‎для‏ ‎таких ‎проверок.

Для ‎демонстрации ‎этих‏ ‎механизмов‏ ‎я ‎создам‏ ‎несколько ‎ролей‏ ‎и ‎групп ‎разных ‎типов. ‎Разумеется,‏ ‎проверим,‏ ‎учитывает ‎ли‏ ‎проверка ‎вложенность.‏ ‎В ‎моих ‎примерах ‎проверяемый ‎пользователь‏ ‎входит‏ ‎только‏ ‎в ‎самую‏ ‎глубоко ‎вложенную‏ ‎группу/роль ‎—‏ ‎№‏ ‎3 ‎(помимо‏ ‎членства ‎в ‎одной-двух ‎стандартных).

Роли ‎базы‏ ‎данных

Анализируя ‎системные‏ ‎представления‏ ‎Sys.Database_Principals и ‎Sys.Database_Role_Members, вы ‎получите‏ ‎полную ‎картину‏ ‎о ‎членстве ‎в ‎группах.

Однако,‏ ‎как‏ ‎правило, ‎полная‏ ‎картина ‎нам‏ ‎не ‎требуется. ‎Достаточно ‎просто ‎проверить‏ ‎принадлежность‏ ‎текущего ‎пользователя‏ ‎к ‎одной‏ ‎конкретной ‎роли. ‎Для ‎такой ‎задачи‏ ‎имеется‏ ‎более‏ ‎простая ‎функция‏ ‎Is_Member. Удобно, ‎что‏ ‎она ‎сама‏ ‎умеет‏ ‎работать ‎с‏ ‎вложенными ‎ролями.

У ‎этой ‎функции ‎есть‏ ‎расширенная ‎версия‏ ‎—‏ ‎Is_RoleMember, у ‎которой ‎есть‏ ‎второй ‎параметр,‏ ‎через ‎который ‎можно ‎указать‏ ‎идентификатор‏ ‎пользователя ‎(database_principal),‏ ‎членство ‎которого‏ ‎хотим ‎проверить.

Группы ‎Active ‎Directory

Функция ‎Is_Member умеет‏ ‎также‏ ‎работать ‎с‏ ‎группами ‎Active‏ ‎Directory. ‎И ‎тоже ‎с ‎учётом‏ ‎вложенности.

Учтите,‏ ‎что‏ ‎эта ‎функция‏ ‎ориентируется ‎на‏ ‎SID’ы ‎групп,‏ ‎рассчитанные‏ ‎при ‎входе‏ ‎пользователя. ‎Поэтому, ‎если ‎пользователь ‎был‏ ‎включён ‎в‏ ‎группу‏ ‎после ‎соединения ‎с‏ ‎сервером, ‎придётся‏ ‎переподключиться.

Серверные ‎роли

Вряд ‎ли ‎вам‏ ‎когда-нибудь‏ ‎на ‎практике‏ ‎придётся ‎программно‏ ‎проверять ‎членство ‎в ‎серверной ‎роли,‏ ‎однако‏ ‎такая ‎возможность‏ ‎имеется ‎—‏ ‎представление ‎Sys.Server_Role_Members.

А ‎также ‎функция ‎Is_SrvRoleMember, которая‏ ‎работает‏ ‎аналогично‏ ‎Is_RoleMember, но ‎на‏ ‎уровне ‎контекста‏ ‎сервера ‎(login),‏ ‎а‏ ‎не ‎базы‏ ‎данных.

Читать: 1+ мин
logo Фёдор Самородов

Как оценить возможность переноса базы данных SQL Server с Enterprise на Standard Edition

Не ‎всякую‏ ‎базу ‎данных ‎можно ‎перенести ‎с‏ ‎Enterprise-редакции ‎на‏ ‎SQL‏ ‎Server ‎Standard ‎Edition.‏ ‎Имеется ‎специальный‏ ‎механизм, ‎показывающий ‎список ‎задействованных‏ ‎enterprise-механизмов,‏ ‎мешающих ‎миграции‏ ‎на ‎стандартную‏ ‎редакцию.

Приходилось ‎ли ‎вам ‎при ‎восстановлении‏ ‎базы‏ ‎данных ‎из‏ ‎резервной ‎копии‏ ‎или ‎при ‎присоединении ‎файлов ‎базы‏ ‎к‏ ‎серверу‏ ‎наблюдать ‎сообщения‏ ‎об ‎ошибке,‏ ‎при ‎том,‏ ‎что‏ ‎на ‎исходном‏ ‎сервере ‎база ‎восстанавливается/присоединяется ‎нормально?

Часто ‎это‏ ‎происходит ‎при‏ ‎попытке‏ ‎переноса ‎базы ‎с‏ ‎корпоративной ‎(Enterprise‏ ‎Edition) ‎на ‎стандартную ‎(Standatd‏ ‎Edition)‏ ‎редакцию ‎SQL-сервера.

Прежде‏ ‎чем ‎осуществлять‏ ‎такой ‎перенос, ‎полезно ‎проверить, ‎а‏ ‎не‏ ‎используются ‎ли‏ ‎в ‎вашей‏ ‎базе ‎механизмы, ‎работающие ‎только ‎в‏ ‎корпоративной‏ ‎редакции‏ ‎SQL-сервера. ‎Если‏ ‎задействована ‎хоть‏ ‎одна ‎enterprise-функция,‏ ‎то‏ ‎перенести ‎базу‏ ‎на ‎standard-редакцию ‎не ‎получится.

А ‎в‏ ‎случае, ‎если‏ ‎вы‏ ‎твёрдо ‎вознамерились ‎перенести‏ ‎базу ‎на‏ ‎сервер ‎стандартной ‎редакции, ‎было‏ ‎бы‏ ‎здорово ‎сразу‏ ‎увидеть ‎список‏ ‎всех ‎механизмов, ‎которые ‎придётся ‎отключить.

Проверить‏ ‎использование‏ ‎корпоративных ‎механизмов,‏ ‎которые ‎помешают‏ ‎такой ‎миграции ‎можно ‎при ‎помощи‏ ‎специального‏ ‎системного‏ ‎представления ‎http://Sys.DM_DB_Persisted_SKU_Features.

Вот‏ ‎так:


Читать: 2+ мин
logo Фёдор Самородов

Что делать, если LOGON-триггер сбрасывает все подключения к SQL-серверу

Триггер ‎входа‏ ‎— ‎очень ‎полезный ‎механизм. Однако, ‎обращаться‏ ‎с ‎ним‏ ‎следует‏ ‎осторожно. ‎LOGON-триггеры ‎срабатывают‏ ‎ещё ‎до‏ ‎того, ‎как ‎пользователь ‎начнёт‏ ‎работу‏ ‎с ‎SQL-сервером,‏ ‎поэтому ‎если‏ ‎такой ‎триггер ‎написан ‎неаккуратно ‎или‏ ‎срабатывает‏ ‎с ‎ошибкой,‏ ‎пользователи, ‎включая‏ ‎администраторов, ‎просто ‎не ‎смогут ‎подключиться‏ ‎к‏ ‎серверу.

Вот‏ ‎пример ‎триггера‏ ‎входа, ‎который‏ ‎умышленно ‎написан‏ ‎так,‏ ‎чтобы ‎сбрасывать‏ ‎все ‎попытки ‎подключения ‎к ‎серверу:

Теперь‏ ‎при ‎попытке‏ ‎установить‏ ‎соединение ‎с ‎SQL-сервером,‏ ‎получаем ‎сообщение‏ ‎об ‎ошибке, ‎случившейся ‎во‏ ‎время‏ ‎выполнения ‎триггера‏ ‎входа:

Если ‎вы‏ ‎попали ‎в ‎такую ‎ситуацию, ‎придётся‏ ‎воспользоваться‏ ‎специальной ‎лазейкой,‏ ‎которая ‎позволяет‏ ‎администратору ‎подключиться ‎к ‎SQL-серверу ‎в‏ ‎обход‏ ‎LOGON-триггеров.‏ ‎Такое ‎«сервисное»‏ ‎подключение ‎доступно‏ ‎только ‎членам‏ ‎серверной‏ ‎роли ‎SysAdmin.‏ ‎Обратите ‎внимание, ‎что ‎возможность ‎удалённого‏ ‎сервисного ‎подключения‏ ‎может‏ ‎быть ‎отключена ‎в‏ ‎настройках, ‎тогда‏ ‎придётся ‎работать ‎прямо ‎на‏ ‎сервере.

В‏ ‎утилите ‎SQLCmd‏ ‎воспользоваться ‎сервисным‏ ‎подключением ‎можно, ‎указав ‎параметр ‎-A:

А‏ ‎при‏ ‎подключении ‎из‏ ‎студии ‎используйте‏ ‎префикс ‎ADMIN: перед ‎именем ‎сервера. ‎Вот‏ ‎так:

Такое‏ ‎подключение‏ ‎не ‎предназначено‏ ‎для ‎полноценной‏ ‎работы ‎с‏ ‎данными,‏ ‎только ‎для‏ ‎решения ‎проблем ‎с ‎доступностью ‎сервера.‏ ‎Но ‎удалить‏ ‎или‏ ‎отключить ‎триггер ‎вы‏ ‎сможете.

Читать: 3+ мин
logo Фёдор Самородов

Как проверить существование временной таблицы

SQL ‎Server‏ ‎умеет ‎работать ‎c ‎временными ‎таблицами.‏ ‎Названия ‎у‏ ‎таких‏ ‎таблиц ‎начинаются ‎с‏ ‎одной ‎или‏ ‎с ‎двух ‎решёток ‎(#).‏ ‎Временные‏ ‎таблицы, ‎очевидно,‏ ‎придуманы ‎для‏ ‎того, ‎чтобы ‎хранить ‎в ‎них‏ ‎данные‏ ‎временно. ‎Например,‏ ‎для ‎сохранения‏ ‎промежуточных ‎результатов ‎каких-либо ‎вычислений. ‎Или‏ ‎для‏ ‎передачи‏ ‎каких-то ‎данных‏ ‎от ‎одного‏ ‎процесса ‎другому.

Иногда‏ ‎требуется‏ ‎проверить, ‎была‏ ‎ли ‎уже ‎создана ‎определённая ‎временная‏ ‎таблица ‎или‏ ‎нет.‏ ‎Как ‎это ‎правильно‏ ‎сделать?

Если ‎речь‏ ‎идёт ‎о ‎глобальной ‎временной‏ ‎таблице,‏ ‎то ‎проверить‏ ‎её ‎наличие‏ ‎можно ‎традиционным ‎способом ‎— ‎заглянув‏ ‎в‏ ‎список ‎таблиц.‏ ‎Только ‎не‏ ‎забудьте ‎сделать ‎поправку ‎на ‎то,‏ ‎что‏ ‎все‏ ‎временные ‎таблицы‏ ‎— ‎и‏ ‎глобальные ‎и‏ ‎локальные‏ ‎— ‎создаются‏ ‎не ‎в ‎текущей ‎пользовательской ‎базе‏ ‎данных, ‎а‏ ‎в‏ ‎системной ‎базе ‎TempDB.

Посмотрите‏ ‎на ‎пример.‏ ‎Один ‎процесс ‎создал ‎глобальную‏ ‎временную‏ ‎таблицу. ‎Теперь‏ ‎этот ‎и‏ ‎все ‎другие ‎процессы ‎могут ‎обращаться‏ ‎к‏ ‎ней, ‎как‏ ‎к ‎обыкновенной‏ ‎таблице. ‎В ‎том ‎числе, ‎они‏ ‎увидят‏ ‎её‏ ‎в ‎системных‏ ‎каталогах ‎sys.Tables и‏ ‎Information_Schema.Tables.

Годится. ‎Однако,‏ ‎такой‏ ‎механизм ‎проверки‏ ‎не ‎сработает, ‎если ‎речь ‎идёт‏ ‎о ‎локальных‏ ‎временных‏ ‎таблицах. ‎Ведь ‎такие‏ ‎таблицы ‎создаются‏ ‎индивидуально ‎для ‎каждого ‎сеанса,‏ ‎и‏ ‎в ‎разных‏ ‎сеансах ‎могут‏ ‎оказаться ‎таблицы ‎с ‎одинаковыми ‎названиями.‏ ‎Чтобы‏ ‎не ‎было‏ ‎конфликта ‎имён,‏ ‎сервер ‎переименовывает ‎локальные ‎таблицы, ‎создавая‏ ‎их‏ ‎в‏ ‎TempDB.

Вот ‎я‏ ‎создаю ‎в‏ ‎двух ‎сеансах‏ ‎локальные‏ ‎временные ‎таблицы‏ ‎с ‎одинаковыми ‎названиями. ‎В ‎каждом‏ ‎сеансе ‎сервер‏ ‎отличает‏ ‎свою ‎таблицу ‎от‏ ‎чужих, ‎но‏ ‎в ‎системных ‎каталогах ‎они‏ ‎видны‏ ‎все ‎сразу:

Если‏ ‎посмотреть ‎внимательнее,‏ ‎то ‎можно ‎заметить, ‎что ‎к‏ ‎названиям‏ ‎таблиц ‎сервер‏ ‎дописывает ‎уникальное‏ ‎окончание, ‎по ‎которому ‎он ‎и‏ ‎определяет‏ ‎чья‏ ‎это ‎таблица:

Возиться‏ ‎с ‎этими‏ ‎окончаниями ‎в‏ ‎SQL-коде‏ ‎не ‎хотелось‏ ‎бы. ‎И ‎не ‎нужно. ‎Потому‏ ‎что ‎у‏ ‎нас‏ ‎есть ‎функция ‎Object_ID, которая‏ ‎автоматически ‎выбирает‏ ‎нужную ‎таблицу:

Если ‎объект ‎с‏ ‎заданным‏ ‎названиям ‎существует,‏ ‎то ‎функция‏ ‎Object_ID вернёт ‎его ‎идентификатор, ‎а ‎если‏ ‎нет‏ ‎— ‎NULL.‏ ‎Таким ‎образом‏ ‎мы ‎сможем ‎удобно ‎и ‎надёжно‏ ‎проверить‏ ‎наличие‏ ‎даже ‎такого‏ ‎необычного ‎объекта,‏ ‎как ‎локальная‏ ‎временная‏ ‎таблица:

У ‎этой‏ ‎функции ‎есть ‎необязательный ‎второй ‎параметр,‏ ‎который ‎можно‏ ‎использовать‏ ‎для ‎указания ‎конкретного‏ ‎типа ‎объекта.‏ ‎«U» ‎означает, ‎что ‎мы‏ ‎ищем‏ ‎именно ‎таблицу.

Читать: 3+ мин
logo Фёдор Самородов

Шифруйте резервные копии баз данных в SQL-сервере

Если ‎вы‏ ‎озабочены ‎защитой ‎данных, ‎то ‎в‏ ‎вашем ‎распоряжении‏ ‎большой‏ ‎набор ‎механизмов, ‎предоставляемых‏ ‎СУБД. ‎Однако,‏ ‎большинство ‎из ‎них ‎работают‏ ‎только‏ ‎тогда, ‎когда‏ ‎данные ‎находятся‏ ‎в ‎работающей ‎базе. ‎А ‎что‏ ‎происходит,‏ ‎когда ‎данные‏ ‎покидают ‎SQL-сервер,‏ ‎например, ‎после ‎резервного ‎копирования? ‎Если‏ ‎злоумышленник‏ ‎украл‏ ‎резервную ‎копию‏ ‎вашей ‎базы‏ ‎данных, ‎то,‏ ‎восстановив‏ ‎её ‎на‏ ‎своём ‎сервере, ‎он ‎увидит ‎все‏ ‎ваши ‎данные!

Поэтому‏ ‎имеет‏ ‎смысл ‎защитить ‎резервную‏ ‎копию ‎при‏ ‎помощи ‎шифрования. ‎Это ‎можно‏ ‎сделать‏ ‎просто ‎зашифровав‏ ‎саму ‎базу‏ ‎данных, ‎но ‎постоянная ‎работа ‎с‏ ‎зашифрованной‏ ‎базой ‎данных‏ ‎может ‎привести‏ ‎к ‎снижению ‎производительности. ‎Прежде ‎чем‏ ‎шифровать‏ ‎базу,‏ ‎рассмотрите ‎возможность‏ ‎отдельного ‎шифрования‏ ‎резервных ‎копий.

SQL-сервер‏ ‎шифрует‏ ‎резервную ‎копию‏ ‎ключом, ‎который ‎сохраняется ‎вместе ‎с‏ ‎самой ‎резервной‏ ‎копией.‏ ‎Поэтому ‎этот ‎ключ‏ ‎тоже ‎нужно‏ ‎зашифровать. ‎Это ‎делается ‎при‏ ‎помощи‏ ‎сертификата, ‎который‏ ‎хранится ‎отдельно‏ ‎от ‎базы ‎и ‎не ‎попадает‏ ‎в‏ ‎резервную ‎копию.

Сам‏ ‎этот ‎сертификат‏ ‎защищается ‎мастер-ключом. ‎Если ‎вы ‎раньше‏ ‎не‏ ‎использовали‏ ‎криптографию ‎в‏ ‎SQL-сервере, ‎то,‏ ‎возможно, ‎мастер-ключа‏ ‎у‏ ‎вас ‎тоже‏ ‎нет ‎и ‎его ‎придётся ‎создать.‏ ‎Вот ‎так:

Обратите‏ ‎внимание,‏ ‎что ‎создав ‎сертификат,‏ ‎я ‎сразу‏ ‎сохранил ‎его ‎в ‎файл.‏ ‎Этот‏ ‎файл ‎понадобится,‏ ‎если ‎вы‏ ‎захотите ‎восстановить ‎базу ‎данных ‎из‏ ‎зашифрованной‏ ‎резервной ‎копии‏ ‎на ‎другом‏ ‎сервере. ‎Не ‎потеряйте ‎его!

Всё, ‎теперь‏ ‎можно‏ ‎создавать‏ ‎зашифрованные ‎резервные‏ ‎копии. ‎Если‏ ‎вы ‎делаете‏ ‎это‏ ‎командой ‎BACKUP‏ ‎DATABASE, ‎то ‎добавьте ‎указание ‎WITH‏ ‎ENCRYPTION:

А ‎если‏ ‎пользуетесь‏ ‎интерфейсом, ‎то ‎загляните‏ ‎на ‎последнюю‏ ‎закладку:

Посмотрим ‎на ‎результаты. ‎Вот‏ ‎что‏ ‎получит ‎злоумышленник,‏ ‎украв ‎не‏ ‎защищённую ‎резервную ‎копию:

Как ‎видите, ‎всё‏ ‎содержимое‏ ‎легко ‎читается.‏ ‎А ‎вот‏ ‎так ‎выглядит ‎зашифрованная ‎копия:

При ‎планировании‏ ‎защиты‏ ‎резервных‏ ‎копий ‎учтите,‏ ‎что ‎такое‏ ‎шифрование ‎имеется‏ ‎не‏ ‎во ‎всех‏ ‎версиях ‎SQL-сервера. ‎Если ‎вы ‎пользуетесь‏ ‎версией ‎младше‏ ‎2014-й,‏ ‎то ‎придётся ‎либо‏ ‎шифровать ‎саму‏ ‎базу, ‎либо ‎пользоваться ‎дополнительными‏ ‎инструментами.

Читать: 2+ мин
logo Фёдор Самородов

Что делать, если в SQL Server'е не осталось ни одного администратора

Начиная ‎с‏ ‎2008-й ‎версии, ‎администраторы ‎Windows ‎уже‏ ‎не ‎являются‏ ‎по‏ ‎умолчанию ‎администраторами ‎SQL-сервера.‏ ‎Это ‎означает,‏ ‎что ‎может ‎возникнуть ‎ситуация,‏ ‎при‏ ‎которой ‎нет‏ ‎ни ‎одной‏ ‎учётной ‎записи, ‎способной ‎управлять ‎SQL-сервером.

Например,‏ ‎вы‏ ‎назначили ‎какую-то‏ ‎учётную ‎запись‏ ‎Windows ‎администратором ‎SQL-сервера, ‎а ‎потом‏ ‎эту‏ ‎учётную‏ ‎запись ‎удалили.‏ ‎Или ‎забыли‏ ‎пароли ‎ко‏ ‎всем‏ ‎учётным ‎записям,‏ ‎которые ‎исполняли ‎роль ‎sysadmin.

Это ‎не‏ ‎просто ‎теоретическая‏ ‎возможность!‏ ‎На ‎практике ‎я‏ ‎периодически ‎сталкиваюсь‏ ‎с ‎SQL-серверами, ‎над ‎которыми‏ ‎потерян‏ ‎контроль. ‎То‏ ‎есть ‎сам‏ ‎по ‎себе ‎SQL-сервер ‎работает ‎нормально,‏ ‎все‏ ‎базы ‎данных‏ ‎функционируют, ‎но‏ ‎никто ‎не ‎может ‎этим ‎сервером‏ ‎управлять.

Для‏ ‎выхода‏ ‎из ‎такой‏ ‎ситуации ‎Микрософт‏ ‎оставил ‎специальную‏ ‎лазейку.

Найдите‏ ‎в ‎списке‏ ‎windows-служб ‎SQL ‎Server ‎и ‎откройте‏ ‎окно ‎со‏ ‎свойствами:

Остановите‏ ‎службу:

Когда ‎служба ‎остановится,‏ ‎на ‎той‏ ‎же ‎закладке ‎окна ‎свойств‏ ‎службы‏ ‎откроется ‎возможность‏ ‎задать ‎дополнительные‏ ‎параметры ‎здя ‎запуска ‎службы. ‎Введите‏ ‎в‏ ‎это ‎поле‏ ‎параметр ‎«-m» и‏ ‎снова ‎запустите ‎службу.

Запущенный ‎таким ‎образом‏ ‎SQL-сервер‏ ‎позволит‏ ‎подключиться ‎локальному‏ ‎администратору ‎независимо‏ ‎от ‎настроек‏ ‎аутентификации.‏ ‎Вы ‎можете‏ ‎от ‎имени ‎локального ‎администратора ‎запустить‏ ‎Management ‎Studio‏ ‎или‏ ‎SQLCmd ‎и ‎восстановить‏ ‎административные ‎учётные‏ ‎записи. ‎После ‎этого ‎перезапустите‏ ‎службу‏ ‎в ‎обычном‏ ‎режиме ‎(без‏ ‎параметра ‎«-m»)

Читать: 3+ мин
logo Фёдор Самородов

Как применить операцию сразу ко всем таблицам или ко всем базам данных

Администраторам ‎часто‏ ‎бывает ‎необходимо ‎перебрать ‎все ‎таблицы‏ ‎базы ‎данных,‏ ‎чтобы‏ ‎над ‎каждой ‎таблицей‏ ‎произвести ‎какое-то‏ ‎действие. ‎Например, ‎перестроить ‎индексы.‏ ‎

Традиционно‏ ‎для ‎такого‏ ‎перебора ‎можно‏ ‎использовать ‎курсор. ‎Но ‎есть ‎способ‏ ‎проще‏ ‎- ‎процедура‏ ‎sp_MSForEachTable. Ей ‎можно‏ ‎передать ‎текст ‎команды ‎или ‎запроса,‏ ‎который‏ ‎будет‏ ‎выполнен ‎для‏ ‎каждой ‎таблицы‏ ‎в ‎базе.‏ ‎Команда,‏ ‎разумеется, ‎параметризуется‏ ‎- ‎вместо ‎вопросительного ‎знака ‎будет‏ ‎подставлено ‎название‏ ‎таблицы.

Посмотрите‏ ‎на ‎сигнатуру ‎этой‏ ‎процедуры:

За ‎один‏ ‎вызов ‎вы ‎можете ‎передать‏ ‎ей‏ ‎три ‎команды,‏ ‎которые ‎будут‏ ‎выполнены ‎для ‎каждой ‎таблицы, ‎плюс‏ ‎начальное‏ ‎и ‎конечное‏ ‎действия ‎для‏ ‎всего ‎пакета ‎команд, ‎а ‎также‏ ‎указать‏ ‎условие‏ ‎включения ‎таблицы‏ ‎в ‎перебор.‏ ‎Параметр ‎@ReplaceChar предназначен‏ ‎для‏ ‎запросов, ‎в‏ ‎которых ‎не ‎получается ‎использовать ‎вопросительный‏ ‎знак ‎для‏ ‎параметризации.

Каждая‏ ‎из ‎трёх ‎команд‏ ‎может ‎содержать‏ ‎больше ‎одного ‎SQL-запроса. ‎При‏ ‎написании‏ ‎фильтра ‎@WhereAnd учтите,‏ ‎что ‎ваша‏ ‎строка ‎будет ‎встроена ‎внутри ‎процедуры‏ ‎в‏ ‎более ‎сложный‏ ‎запрос ‎к‏ ‎системным ‎таблицам, ‎поэтому ‎используйте ‎для‏ ‎фильтрации‏ ‎столбцы‏ ‎из ‎SysObjects. Например:

Имеется‏ ‎аналогичная ‎процедура‏ ‎для ‎перебора‏ ‎всех‏ ‎баз ‎данных‏ ‎на ‎сервере ‎- ‎sp_MSForEachDB:

С ‎её‏ ‎помощью ‎вы‏ ‎сможете‏ ‎выполнить ‎однотипный ‎набор‏ ‎действий ‎над‏ ‎каждой ‎базой ‎на ‎сервере:


Читать: 1+ мин
logo Фёдор Самородов

Как отлаживать код, использующий привязку к текущему пользователю

В ‎реляционной‏ ‎базе ‎данных ‎нельзя ‎назначать ‎права‏ ‎на ‎строки.‏ ‎Поэтому,‏ ‎для ‎защиты ‎отдельных‏ ‎строк ‎часто‏ ‎используют ‎представление ‎(VIEW) ‎с‏ ‎привязкой‏ ‎к ‎идентификатору‏ ‎текущего ‎пользователя.‏ ‎Это, ‎пожалуй, ‎самый ‎распространённый, ‎но‏ ‎далеко‏ ‎не ‎единственный‏ ‎сценарий ‎использования‏ ‎в ‎коде ‎обращений ‎к ‎текущему‏ ‎контексту‏ ‎безопасности.

Как‏ ‎отлаживать ‎такой‏ ‎код? ‎Можно‏ ‎открыть ‎несколько‏ ‎соединений‏ ‎с ‎сервером‏ ‎от ‎имени ‎разных ‎пользователей ‎и‏ ‎смотреть ‎на‏ ‎результаты‏ ‎одного ‎и ‎того‏ ‎же ‎запроса‏ ‎в ‎разных ‎окнах. ‎Но‏ ‎если‏ ‎это ‎приходится‏ ‎делать ‎по‏ ‎многу ‎раз, ‎переключение ‎между ‎соединениями‏ ‎начинает‏ ‎утомлять ‎и‏ ‎отвлекать.

Альтернативный ‎вариант‏ ‎— ‎создайте ‎для ‎пользователя ‎свой‏ ‎собственный‏ ‎связанный‏ ‎сервер ‎(Linked‏ ‎Server), ‎который‏ ‎ссылается ‎сам‏ ‎на‏ ‎себя. ‎Вот‏ ‎так:

И ‎в ‎настройках ‎этого ‎связанного‏ ‎сервера ‎укажите‏ ‎контекст‏ ‎безопасности, ‎в ‎котором‏ ‎хотите ‎провести‏ ‎отладку:


Теперь ‎можно ‎смотреть ‎на‏ ‎данные‏ ‎глазами ‎разных‏ ‎пользователей ‎через‏ ‎одно ‎подключение ‎и ‎даже ‎из‏ ‎одного‏ ‎окна:

Описанный ‎приём‏ ‎— ‎не‏ ‎единственный. ‎Но ‎он ‎самый ‎простой‏ ‎и‏ ‎не‏ ‎требует ‎вмешательства‏ ‎в ‎саму‏ ‎отлаживаемую ‎базу‏ ‎данных.

Читать: 4+ мин
logo Фёдор Самородов

Как восстановить согласованную резервную копию нескольких баз данных

Для ‎администратора‏ ‎баз ‎данных ‎резервное ‎копирование ‎—‏ ‎вещь ‎обязательная.‏ ‎Не‏ ‎важно ‎какими ‎базами‏ ‎вы ‎управляете,‏ ‎большими ‎или ‎маленькими, ‎делать‏ ‎бэкапы‏ ‎необходимо. ‎Разработчики‏ ‎СУБД ‎это‏ ‎понимают ‎и ‎стараются ‎сделать ‎процедуру‏ ‎резервного‏ ‎копирования ‎максимально‏ ‎простой ‎и‏ ‎понятной ‎для ‎администратора. ‎Но ‎есть‏ ‎в‏ ‎резервном‏ ‎копировании ‎баз‏ ‎данных ‎один‏ ‎момент, ‎в‏ ‎котором‏ ‎СУБД ‎вам‏ ‎помочь ‎не ‎сможет…

Современные ‎приложения ‎всё‏ ‎чаще ‎проектируются‏ ‎так,‏ ‎чтобы ‎работать ‎с‏ ‎данными ‎не‏ ‎в ‎одной ‎базе ‎данных,‏ ‎а‏ ‎в ‎нескольких.‏ ‎Это ‎действительно‏ ‎полезно ‎— ‎таким ‎образом ‎можно‏ ‎повысить‏ ‎масштабируемость, ‎производительность,‏ ‎надёжность ‎и‏ ‎управляемость ‎приложения. ‎Но, ‎как ‎всегда‏ ‎бывает‏ ‎в‏ ‎инженерном ‎деле,‏ ‎это ‎не‏ ‎обходится ‎без‏ ‎сопутствующих‏ ‎недостатков. ‎Главный‏ ‎из ‎которых ‎— ‎усложнение ‎системы.‏ ‎Возможности ‎системы‏ ‎растут‏ ‎вместе ‎с ‎её‏ ‎сложностью, ‎что‏ ‎повышает ‎требования ‎к ‎обслуживанию‏ ‎многобазовых‏ ‎приложений. ‎Одна‏ ‎из ‎проблем,‏ ‎которую ‎придётся ‎решать ‎при ‎эксплуатации‏ ‎таких‏ ‎приложений ‎—‏ ‎создание ‎(и‏ ‎последующее ‎восстановление) ‎согласованных ‎резервных ‎копий‏ ‎нескольких‏ ‎баз‏ ‎данных.

Перед ‎вами‏ ‎аналог ‎приложения,‏ ‎работающего ‎с‏ ‎несколькими‏ ‎БД. ‎Оно‏ ‎постоянно ‎обрабатывает ‎данные ‎в ‎базах,‏ ‎согласовывая ‎изменения‏ ‎при‏ ‎помощи ‎транзакций.

Если ‎вы‏ ‎будете ‎восстанавливать‏ ‎из ‎резервных ‎копий ‎каждую‏ ‎из‏ ‎баз ‎независимо‏ ‎друг ‎от‏ ‎друга, ‎то ‎базы ‎восстановятся ‎в‏ ‎состояниях‏ ‎на ‎разные‏ ‎моменты ‎времени,‏ ‎что ‎означает ‎нарушение ‎целостности. ‎Каждая‏ ‎база‏ ‎данных‏ ‎вроде ‎бы‏ ‎восстановлена ‎и‏ ‎сама ‎по‏ ‎себе‏ ‎находится ‎в‏ ‎согласованном ‎состоянии, ‎но ‎приложению ‎необходимо,‏ ‎что ‎ещё‏ ‎и‏ ‎все ‎базы ‎были‏ ‎согласованы ‎между‏ ‎собой.

SQL ‎Server ‎позволяет ‎восстанавливать‏ ‎базу‏ ‎в ‎состоянии‏ ‎не ‎только‏ ‎на ‎момент ‎создания ‎резервной ‎копии,‏ ‎но‏ ‎и ‎на‏ ‎любой ‎произвольный‏ ‎момент ‎времени. ‎Чтобы ‎добиться ‎максимальной‏ ‎точности,‏ ‎следует‏ ‎восстанавливать ‎состояние‏ ‎базы ‎на‏ ‎момент ‎фиксации‏ ‎определённой‏ ‎транзакции, ‎а‏ ‎саму ‎транзакцию ‎провести ‎так, ‎чтобы‏ ‎она ‎внесла‏ ‎изменения‏ ‎сразу ‎во ‎все‏ ‎базы.

Можно, ‎к‏ ‎примеру, ‎создать ‎в ‎каждой‏ ‎базе‏ ‎табличку ‎и‏ ‎в ‎транзакции‏ ‎добавлять ‎в ‎неё ‎строку. ‎А‏ ‎чтобы‏ ‎эту ‎транзакцию‏ ‎при ‎восстановлении‏ ‎можно ‎было ‎отличить ‎от ‎остальных,‏ ‎снабдим‏ ‎её‏ ‎меткой.

Теперь, ‎когда‏ ‎эта ‎метка‏ ‎сохранена ‎в‏ ‎журнале‏ ‎транзакций, ‎можно‏ ‎создать ‎резервную ‎копию ‎журнала. ‎А‏ ‎при ‎восстановлении‏ ‎не‏ ‎забудьте ‎указать ‎параметр‏ ‎STOPATMARK ‎(или‏ ‎STOPBEFOREMARK), ‎чтобы ‎все ‎базы‏ ‎восстановились‏ ‎на ‎момент‏ ‎фиксации ‎нашей‏ ‎контрольной ‎транзакции.

Проверяем ‎базы ‎после ‎восстановления‏ ‎из‏ ‎резервной ‎копии:

Аналогично‏ ‎можно ‎восстанавливать‏ ‎согласованные ‎резервные ‎копии ‎баз ‎данных,‏ ‎работающих‏ ‎на‏ ‎разных ‎серверах.‏ ‎Только ‎не‏ ‎забудьте ‎при‏ ‎этом‏ ‎модифицировать ‎код‏ ‎контрольной ‎транзакции ‎так, ‎чтобы ‎транзакционная‏ ‎метка ‎распространялась‏ ‎на‏ ‎все ‎серверы.

Читать: 4+ мин
logo Фёдор Самородов

Как ограничить список баз данных, видимых пользователю

Если ‎пользователь‏ ‎не ‎является ‎администратором, ‎то ‎незачем‏ ‎ему ‎показывать‏ ‎все‏ ‎базы ‎данных, ‎имеющиеся‏ ‎на ‎сервере.‏ ‎Разумно ‎было ‎бы ‎показывать‏ ‎пользователю‏ ‎только ‎те‏ ‎базы, ‎которые‏ ‎ему ‎нужны ‎и ‎к ‎которым‏ ‎у‏ ‎него ‎есть‏ ‎доступ.

Хорошо ‎быть‏ ‎администратором. ‎Подключаемся ‎к ‎серверу, ‎разворачиваем‏ ‎список‏ ‎баз‏ ‎данных ‎и‏ ‎до ‎каждой‏ ‎базы ‎нам‏ ‎есть‏ ‎дело!

А ‎в‏ ‎сценариях ‎хостинга ‎или ‎персональной ‎аналитики‏ ‎обычно ‎другая‏ ‎картина.‏ ‎Разворачиваем ‎огромный ‎список‏ ‎баз ‎и‏ ‎листаем, ‎листаем, ‎листаем ‎его‏ ‎в‏ ‎поисках ‎той‏ ‎единственной, ‎к‏ ‎которой ‎у ‎нас ‎есть ‎доступ.

Вот‏ ‎один‏ ‎из ‎наших‏ ‎учебных ‎серверов.‏ ‎У ‎каждого ‎пользователя ‎есть ‎своя‏ ‎база‏ ‎данных,‏ ‎в ‎которой‏ ‎он ‎—‏ ‎полноправный ‎хозяин.‏ ‎Есть‏ ‎также ‎несколько‏ ‎баз, ‎в ‎которые ‎пользователь ‎может‏ ‎заглянуть ‎с‏ ‎ограниченными‏ ‎правами. ‎А ‎к‏ ‎большинству ‎баз‏ ‎данных ‎у ‎пользователя ‎вообще‏ ‎нет‏ ‎никакого ‎доступа.‏ ‎Но ‎все‏ ‎эти ‎факторы ‎не ‎принимаются ‎во‏ ‎внимание‏ ‎SQL-сервером, ‎мы‏ ‎всё ‎равно‏ ‎видим ‎весь ‎список:

Давайте ‎посмотрим, ‎что‏ ‎тут‏ ‎можно‏ ‎придумать.

Пользователь ‎«Фёдор‏ ‎Самородов», ‎подключившись,‏ ‎видит ‎список‏ ‎баз‏ ‎данных ‎благодаря‏ ‎тому, ‎что ‎у ‎роли ‎public есть‏ ‎разрешение ‎VIEW‏ ‎ANY‏ ‎DATABASE.

Вы ‎можете ‎это‏ ‎разрешение ‎отозвать‏ ‎(тогда ‎это ‎изменит ‎картину‏ ‎для‏ ‎всех ‎пользователей),‏ ‎либо ‎запретить‏ ‎индивидуально ‎для ‎некоторых ‎пользователей. ‎Попробуем‏ ‎запретить‏ ‎просмотр ‎этих‏ ‎метаданных ‎для‏ ‎нашего ‎пользователя:

Это ‎сработало! ‎Правда, ‎стало‏ ‎ещё‏ ‎хуже‏ ‎— ‎теперь‏ ‎мы ‎не‏ ‎видим ‎вообще‏ ‎никаких‏ ‎баз, ‎кроме‏ ‎master и ‎tempdb.

Заметьте, ‎что ‎на ‎сам‏ ‎доступ ‎к‏ ‎базам‏ ‎это ‎не ‎повлияло.‏ ‎Если ‎мы‏ ‎знаем ‎название ‎нужной ‎базы‏ ‎данных,‏ ‎то ‎сможем‏ ‎переключиться ‎в‏ ‎её ‎контекст:

К ‎сожалению, ‎добиться ‎желаемой‏ ‎гибкости‏ ‎мы ‎не‏ ‎сможем. ‎В‏ ‎общем ‎случае ‎такая ‎задача ‎не‏ ‎решаема.‏ ‎SQL‏ ‎Server ‎покажет‏ ‎нам ‎только‏ ‎те ‎базы,‏ ‎владельцами‏ ‎которых ‎мы‏ ‎являемся. ‎Причём, ‎учитывается ‎именно ‎фактор‏ ‎владения, ‎членства‏ ‎в‏ ‎роли ‎db_owner недостаточно.

На ‎практике‏ ‎это ‎означает,‏ ‎что ‎вы ‎сможете ‎ограничить‏ ‎видимость‏ ‎баз ‎данных‏ ‎только ‎в‏ ‎тех ‎сценариях, ‎когда ‎пользователи ‎сами‏ ‎владеют‏ ‎своими ‎персональными‏ ‎базами.

Сделаем ‎пользователя‏ ‎владельцем ‎одной ‎из ‎баз:

А ‎теперь‏ ‎обновим‏ ‎список:

Или‏ ‎выполним ‎аналогичный‏ ‎запрос ‎к‏ ‎sys.Databases:

Вот ‎это‏ ‎уже‏ ‎похоже ‎на‏ ‎то, ‎что ‎мы ‎задумали, ‎и‏ ‎это ‎—‏ ‎лучшее,‏ ‎чего ‎мы ‎можем‏ ‎добиться ‎в‏ ‎текущих ‎версиях ‎SQL-сервера.

Читать: 3+ мин
logo Фёдор Самородов

Как ограничить число одновременных подключений к SQL-серверу

Этот ‎вопрос‏ ‎относится ‎к ‎задаче ‎квотирования ‎ресурсов.‏ ‎Обычно ‎администратор‏ ‎желает‏ ‎контролировать ‎ресурсы ‎сервера,‏ ‎которые ‎являются‏ ‎исчерпаемыми ‎или ‎дорогостоящими. ‎Например,‏ ‎занятое‏ ‎место ‎на‏ ‎диске, ‎объём‏ ‎выделенной ‎памяти, ‎процессорное ‎время. ‎Если‏ ‎ваше‏ ‎приложение ‎подключается‏ ‎к ‎СУБД‏ ‎напрямую ‎с ‎клиентской ‎рабочей ‎станции,‏ ‎а‏ ‎не‏ ‎опосредованно ‎через‏ ‎сервер ‎приложения,‏ ‎то ‎таким‏ ‎дорогостоящим‏ ‎ресурсом ‎могут‏ ‎стать ‎открытые ‎сеансы.

Разумеется, ‎разработчик ‎приложения‏ ‎может ‎и,‏ ‎как‏ ‎правило, ‎должен ‎экономить‏ ‎открытые ‎соединения.‏ ‎Для ‎этого ‎у ‎него‏ ‎есть‏ ‎удобные ‎инструменты.‏ ‎Но ‎если‏ ‎приложение ‎запускается ‎на ‎разных ‎рабочих‏ ‎станциях‏ ‎разными ‎пользователями,‏ ‎то ‎от‏ ‎действий ‎разработчика ‎зависит ‎уже ‎не‏ ‎всё.

Пределы‏ ‎на‏ ‎число ‎одновременно‏ ‎открытых ‎подключений‏ ‎можно ‎установить‏ ‎и‏ ‎на ‎сервере‏ ‎баз ‎данных. ‎В ‎SQL ‎Server’е‏ ‎для ‎этого‏ ‎можно‏ ‎использовать ‎триггеры ‎входа‏ ‎(LOGON ‎TRIGGER).‏ ‎Эти ‎триггеры ‎срабатывают ‎после‏ ‎аутентификации‏ ‎(то ‎есть‏ ‎мы ‎уже‏ ‎знаем ‎кто ‎и ‎с ‎какого‏ ‎компьютера‏ ‎желает ‎подключиться),‏ ‎но ‎до‏ ‎создания ‎сеанса ‎(то ‎есть, ‎у‏ ‎нас‏ ‎ещё‏ ‎есть ‎возможность‏ ‎не ‎допустить‏ ‎установления ‎соединения).

В‏ ‎контексте‏ ‎такого ‎триггера‏ ‎вы ‎можете ‎обращаться ‎к ‎системным‏ ‎функциям ‎и‏ ‎представлениям,‏ ‎что ‎даёт ‎возможность‏ ‎принять ‎решение‏ ‎об ‎отмене ‎создания ‎сеанса.

Например,‏ ‎можно‏ ‎проанализировать ‎число‏ ‎уже ‎открытых‏ ‎соединений ‎с ‎этой ‎рабочей ‎станции‏ ‎(здесь‏ ‎мы ‎не‏ ‎даём ‎открывать‏ ‎более ‎10 ‎сеансов ‎с ‎одного‏ ‎компьютера):

Или‏ ‎число‏ ‎открытых ‎сеансов‏ ‎именно ‎этого‏ ‎пользователя:

Разумеется, ‎можно‏ ‎использовать‏ ‎более ‎сложную‏ ‎логику, ‎анализируя ‎уже ‎открытые ‎сеансы‏ ‎по ‎пользователям,‏ ‎компьютерам‏ ‎и ‎приложениям ‎одновременно:

Обратите‏ ‎внимание, ‎что‏ ‎триггеры ‎входа ‎действуют ‎в‏ ‎рамках‏ ‎всего ‎SQL-сервера:

Поэтому‏ ‎обращайтесь ‎с‏ ‎ними ‎очень ‎аккуратно. ‎Если ‎вы‏ ‎допустите‏ ‎ошибку ‎в‏ ‎таком ‎триггере,‏ ‎то ‎подключиться ‎к ‎серверу ‎не‏ ‎сможет‏ ‎никто,‏ ‎включая ‎системного‏ ‎администратора, ‎так‏ ‎как ‎сервер‏ ‎будет‏ ‎сбрасывать ‎любые‏ ‎попытки ‎соединения. ‎А ‎чтобы ‎исправить‏ ‎или ‎отключить‏ ‎триггер,‏ ‎нужно ‎сначала ‎суметь‏ ‎установить ‎соединение.

Читать: 2+ мин
logo Фёдор Самородов

Как получить список объектов Active Directory из Transact-SQL

В ‎различных‏ ‎административных ‎сценариях ‎(автоматизация, ‎интеграция, ‎обслуживание)‏ ‎возникает ‎необходимость‏ ‎обрабатывать‏ ‎внутри ‎SQL-сченария ‎списки‏ ‎объектов ‎Active‏ ‎Directory. ‎В ‎SQL ‎Server’е‏ ‎есть‏ ‎встроенный ‎механизм‏ ‎для ‎работы‏ ‎с ‎Active ‎Directory ‎и ‎пользоваться‏ ‎этим‏ ‎механизмом ‎совсем‏ ‎не ‎сложно.

SQL‏ ‎Server ‎считает ‎Active ‎Directory ‎внешним‏ ‎источником‏ ‎данных,‏ ‎так ‎что‏ ‎обращаться ‎к‏ ‎базе ‎AD‏ ‎можно‏ ‎через ‎механизм‏ ‎связанных ‎серверов ‎(linked ‎servers). ‎Прежде‏ ‎всего ‎администратор‏ ‎SQL‏ ‎Server-а ‎должен ‎создать‏ ‎связанный ‎сервер.‏ ‎Вот ‎так:

Удобно, ‎что ‎в‏ ‎системе‏ ‎уже ‎есть‏ ‎драйвер ‎для‏ ‎чтения ‎данных ‎из ‎Active ‎Directory:

Теперь‏ ‎в‏ ‎свойствах ‎связанного‏ ‎сервера ‎нужно‏ ‎прописать ‎реквизиты ‎учётной ‎записи, ‎из-под‏ ‎которой‏ ‎SQL‏ ‎Server ‎будет‏ ‎обращаться ‎к‏ ‎Active ‎Directory:

Всё‏ ‎готово.‏ ‎Теперь ‎можно‏ ‎обращаться ‎к ‎объектам ‎Active ‎Directory‏ ‎прямо ‎из‏ ‎сценария‏ ‎Transact-SQL. ‎Например, ‎вот‏ ‎так:

Или ‎вот‏ ‎так:

Но ‎лучше, ‎наверное, ‎вот‏ ‎так:


Читать: 1+ мин
logo Фёдор Самородов

Как программно получить исходный код хранимой процедуры в SQL Server

При ‎редактировании‏ ‎хранимой ‎процедуры ‎Management ‎Studio ‎ловко‏ ‎подставляет ‎в‏ ‎редактор‏ ‎её ‎исходный ‎текст.‏ ‎Как ‎самому‏ ‎таким ‎же ‎образом ‎получить‏ ‎доступ‏ ‎к ‎её‏ ‎исходному ‎коду?

Для‏ ‎исследования ‎объектов ‎базы ‎данных ‎(в‏ ‎стиле‏ ‎обратного ‎инжиниринга)‏ ‎в ‎SQL‏ ‎Server’е ‎имеются ‎штатные ‎средства. ‎А‏ ‎именно‏ ‎две‏ ‎полезных ‎хранимых‏ ‎процедуры: ‎sp_Help‏ ‎и ‎sp_HelpText.‏ ‎Пользоваться‏ ‎ими ‎очень‏ ‎просто, ‎посмотрите ‎на ‎пример:


Читать: 5+ мин
logo Фёдор Самородов

Как тестировать и отлаживать базы данных

Автоматическое ‎модульное‏ ‎тестирование ‎(unit ‎test) ‎кода ‎приложения‏ ‎— ‎дело‏ ‎простое‏ ‎и ‎понятное. ‎А‏ ‎как ‎тестировать‏ ‎базу ‎данных? ‎Или ‎приложение,‏ ‎которое‏ ‎работает ‎с‏ ‎базой ‎данных.‏ ‎Ведь ‎база ‎— ‎это ‎не‏ ‎просто‏ ‎программный ‎код,‏ ‎база ‎данных‏ ‎— ‎это ‎объект, ‎сохраняющий ‎своё‏ ‎состояние.‏ ‎И‏ ‎если ‎мы‏ ‎начнём ‎в‏ ‎процессе ‎тестирования‏ ‎изменять‏ ‎данные ‎в‏ ‎базе ‎(а ‎без ‎этого ‎какое‏ ‎же ‎у‏ ‎нас‏ ‎будет ‎тестирование?!), ‎то‏ ‎после ‎каждого‏ ‎теста ‎база ‎будет ‎изменяться.‏ ‎Это‏ ‎может ‎помешать‏ ‎последующим ‎тестам‏ ‎и ‎необратимо ‎испортить ‎базу ‎данных.

Ключ‏ ‎к‏ ‎решению ‎проблемы‏ ‎— ‎транзакции.‏ ‎Одна ‎из ‎особеностей ‎этого ‎механизма‏ ‎состоит‏ ‎в‏ ‎том, ‎что‏ ‎до ‎тех‏ ‎пор, ‎пока‏ ‎транзакция‏ ‎не ‎завершена,‏ ‎вы ‎всегда ‎можете ‎отменить ‎все‏ ‎изменения ‎и‏ ‎вернуть‏ ‎базу ‎в ‎состояние‏ ‎на ‎момент‏ ‎начала ‎транзакции.

Алгоритм ‎такой:

  1. открываем ‎транзакцию;
  2. если‏ ‎нужно,‏ ‎выполняем ‎подготовительные‏ ‎действия ‎для‏ ‎тестирования;
  3. выполняем ‎модульный ‎тест ‎(или ‎просто‏ ‎запускаем‏ ‎сценарий, ‎работу‏ ‎которого ‎хотим‏ ‎проверить);
  4. проверяем ‎результат ‎работы ‎сценария;
  5. отменяем ‎транзакцию,‏ ‎возвращая‏ ‎базу‏ ‎данных ‎в‏ ‎исходное ‎состояние.

Даже‏ ‎если ‎в‏ ‎тестируемом‏ ‎коде ‎останутся‏ ‎незакрытые ‎транзакции, ‎внешний ‎ROLLBACK ‎всё‏ ‎равно ‎откатит‏ ‎все‏ ‎изменения ‎корректно.

Хорошо, ‎если‏ ‎нам ‎нужно‏ ‎протестировать ‎SQL-сценарий ‎или ‎хранимую‏ ‎процедуру.‏ ‎А ‎если‏ ‎мы ‎тестируем‏ ‎приложение, ‎которое ‎само ‎подключается ‎к‏ ‎базе,‏ ‎открывая ‎новое‏ ‎соединение? ‎Кроме‏ ‎того, ‎если ‎мы ‎занимаемся ‎отладкой,‏ ‎то‏ ‎нам‏ ‎наверняка ‎захочется‏ ‎посмотреть ‎на‏ ‎базу ‎глазами‏ ‎самого‏ ‎отлаживаемого ‎приложения.‏ ‎Как ‎быть ‎в ‎таком ‎случае?

Не‏ ‎торопитесь ‎сочинять‏ ‎распределённые‏ ‎транзакции, ‎есть ‎более‏ ‎простое ‎решение!‏ ‎Штатными ‎средствами ‎SQL-сервера ‎вы‏ ‎можете‏ ‎открыть ‎транзакцию‏ ‎на ‎одном‏ ‎соединении, ‎а ‎продолжить ‎её ‎на‏ ‎другом.

Для‏ ‎этого ‎нужно‏ ‎подключиться ‎к‏ ‎серверу, ‎открыть ‎транзакцию, ‎получить ‎маркер‏ ‎этой‏ ‎транзакции,‏ ‎а ‎затем‏ ‎передать ‎этот‏ ‎маркер ‎тестируемому‏ ‎приложению.‏ ‎Оно ‎в‏ ‎своём ‎сеансе ‎присоединится ‎к ‎нашей‏ ‎транзакции ‎и‏ ‎с‏ ‎этого ‎момента ‎мы‏ ‎в ‎своём‏ ‎отладочном ‎сеансе ‎будем ‎видеть‏ ‎данные‏ ‎(а ‎также‏ ‎чувствовать ‎блокировки)‏ ‎точно ‎так, ‎как ‎их ‎видит‏ ‎тестируемое‏ ‎приложение.

Последовательность ‎действий‏ ‎такова:

Начав ‎транзакцию‏ ‎в ‎отладочном ‎сеансе ‎мы ‎должны‏ ‎узнать‏ ‎её‏ ‎идентификатор. ‎Это‏ ‎уникальная ‎строка,‏ ‎по ‎которой‏ ‎сервер‏ ‎различает ‎транзакции.‏ ‎Этот ‎идентификатор ‎надо ‎каким-то ‎образом‏ ‎передать ‎в‏ ‎тестируемое‏ ‎приложение.

Теперь ‎задача ‎приложения‏ ‎— ‎прежде,‏ ‎чем ‎оно ‎начнёт ‎делать‏ ‎то,‏ ‎что ‎ему‏ ‎положено, ‎привязаться‏ ‎к ‎нашей ‎контрольной ‎транзакции.

Затем ‎приложение‏ ‎начинает‏ ‎работать, ‎в‏ ‎том ‎числе‏ ‎запускать ‎свои ‎хранимые ‎процедуры, ‎открывать‏ ‎свои‏ ‎транзакции,‏ ‎менять ‎режим‏ ‎изоляции… ‎Но‏ ‎наш ‎отладочный‏ ‎сеанс‏ ‎всё ‎это‏ ‎время ‎будет ‎находиться ‎внутри ‎той‏ ‎же ‎транзакции,‏ ‎что‏ ‎и ‎приложение.

Допустим, ‎приложение‏ ‎блокирует ‎таблицу‏ ‎и ‎начинает ‎изменять ‎её‏ ‎содержимое.‏ ‎В ‎этот‏ ‎момент ‎никакие‏ ‎другие ‎соединения ‎заглянуть ‎в ‎заблокированную‏ ‎таблицу‏ ‎не ‎могут.‏ ‎Но ‎только‏ ‎не ‎наш ‎отладочный ‎сеанс! ‎Из‏ ‎него‏ ‎мы‏ ‎можем ‎смотреть‏ ‎на ‎базу‏ ‎точно ‎так‏ ‎же,‏ ‎как ‎это‏ ‎делает ‎приложение, ‎так ‎как ‎SQL-сервер‏ ‎считает, ‎что‏ ‎мы‏ ‎находимся ‎в ‎одной‏ ‎транзакции.

В ‎то‏ ‎время ‎как ‎для ‎всех‏ ‎остальных‏ ‎сеансов ‎действия‏ ‎приложения ‎скрыты‏ ‎блокировками…

…наш ‎отладочный ‎сеанс ‎спокойно ‎проходит‏ ‎сквозь‏ ‎блокировки ‎(сервер‏ ‎думает, ‎что‏ ‎это ‎наши ‎собственные ‎блокировки)!

Или ‎представьте,‏ ‎что‏ ‎приложение‏ ‎начинает ‎работать‏ ‎со ‎своими‏ ‎версиями ‎строк‏ ‎в‏ ‎режиме ‎SNAPSHOT.‏ ‎Как ‎заглянуть ‎в ‎эти ‎версии?‏ ‎Даже ‎это‏ ‎возможно,‏ ‎если ‎вы ‎связаны‏ ‎общей ‎транзакцией!

Не‏ ‎забудьте ‎в ‎конце ‎этого‏ ‎увлекательного‏ ‎процесса ‎откатить‏ ‎контрольную ‎транзакцию.‏ ‎Это ‎можно ‎сделать ‎как ‎из‏ ‎отладочного‏ ‎сеанса ‎(если‏ ‎процесс ‎тестирования‏ ‎завершится ‎нормально), ‎так ‎и ‎из‏ ‎самого‏ ‎приложения‏ ‎(если ‎в‏ ‎нём ‎случится‏ ‎что-то ‎непредвиденное).

Читать: 2+ мин
logo Фёдор Самородов

Какую пользу можно извлечь из расширенных свойств объектов БД SQL Server

Микрософт ‎предлагает‏ ‎использовать ‎расширенные ‎свойства ‎(extended ‎properties)‏ ‎объектов ‎в‏ ‎SQL‏ ‎Server’е ‎для ‎взаимодействия‏ ‎с ‎приложением.‏ ‎А ‎можно ‎ли ‎сделать‏ ‎с‏ ‎ними ‎что-то‏ ‎полезное ‎именно‏ ‎в ‎базе ‎данных? ‎Ведь ‎не‏ ‎просто‏ ‎так ‎они‏ ‎вынесены ‎на‏ ‎отдельную ‎закладку ‎в ‎Management ‎Studio!

Да,‏ ‎расширенные‏ ‎свойства‏ ‎можно ‎приспособить‏ ‎для ‎удобного‏ ‎хранения ‎и‏ ‎отображения‏ ‎той ‎информации,‏ ‎с ‎которой ‎вам ‎было ‎бы‏ ‎комфортно ‎работать‏ ‎в‏ ‎графическом ‎интерфейсе. ‎Посмотрите‏ ‎на ‎свойства,‏ ‎которые ‎я ‎добавил ‎к‏ ‎этой‏ ‎хранимой ‎процедуре:

Процедура‏ ‎сама ‎считает‏ ‎сколько ‎раз ‎её ‎вызывали ‎и‏ ‎сама‏ ‎запоминает ‎кто‏ ‎и ‎когда‏ ‎использовал ‎её ‎в ‎последний ‎раз.‏ ‎Добавить‏ ‎такое‏ ‎журналирование ‎было‏ ‎не ‎сложно:

А‏ ‎не ‎лучше‏ ‎ли‏ ‎было ‎хранить‏ ‎эти ‎данные ‎в ‎какой-нибудь ‎таблице?‏ ‎Да, ‎если‏ ‎вы‏ ‎собираетесь ‎обрабатывать ‎эти‏ ‎данные ‎автоматически,‏ ‎то, ‎разумеется, ‎следует ‎использовать‏ ‎традиционный‏ ‎подход. ‎Но‏ ‎если ‎эти‏ ‎данные ‎нужны ‎вам ‎именно ‎при‏ ‎работе‏ ‎в ‎SSMS,‏ ‎то ‎гораздо‏ ‎удобнее ‎будет ‎просто ‎посмотреть ‎их‏ ‎в‏ ‎свойствах‏ ‎процедуры ‎на‏ ‎закладке ‎«Extended‏ ‎properties».

Хотите ‎подарить‏ ‎администратору,‏ ‎который ‎будет‏ ‎обслуживать ‎вашу ‎базу ‎данных ‎небольшую‏ ‎порцию ‎приятных‏ ‎эмоций?‏ ‎Ему ‎будет ‎приятно‏ ‎почувствовать ‎вашу‏ ‎заботу! ‎:) ‎Добавьте ‎немного‏ ‎комфорта‏ ‎к ‎его‏ ‎нелёгкой ‎работе.‏ ‎Например, ‎вот ‎так:


Читать: 3+ мин
logo Фёдор Самородов

Как ускорить восстановление больших баз данных в SQL Server

Все ‎администраторы‏ ‎знают, ‎что ‎восстановление ‎базы ‎данных‏ ‎из ‎резервной‏ ‎копии‏ ‎— ‎процесс ‎не‏ ‎быстрый. ‎Особенно,‏ ‎если ‎база ‎большая.

А ‎что‏ ‎если‏ ‎я ‎скажу,‏ ‎что ‎время‏ ‎восстановления ‎БД ‎можно ‎сократить ‎более‏ ‎чем‏ ‎вдвое ‎при‏ ‎помощи ‎одной‏ ‎простейшей ‎опции?

Давайте ‎проведём ‎эксперимент. ‎Вот‏ ‎база‏ ‎данных‏ ‎размером ‎100‏ ‎ГБ, ‎под‏ ‎завязку ‎заполненная‏ ‎данными.

Все‏ ‎данные ‎этой‏ ‎базы ‎лежат ‎в ‎единственном ‎файле.

Я‏ ‎сделаю ‎резервную‏ ‎копию‏ ‎этой ‎базы ‎и‏ ‎затем ‎восстановлю‏ ‎базу ‎из ‎резервной ‎копии.‏ ‎И‏ ‎резервное ‎копирование‏ ‎и ‎восстановление‏ ‎я ‎провожу ‎самым ‎обыкновенным ‎способом‏ ‎без‏ ‎каких-либо ‎хитроумных‏ ‎настроек.

А ‎теперь‏ ‎посмотрите ‎внимательно ‎на ‎выдачу ‎инструкции‏ ‎RESTORE‏ ‎DATABASE:

Сама‏ ‎команда ‎восстановления‏ ‎сообщает, ‎что‏ ‎она ‎выполнялась‏ ‎3331‏ ‎секунду ‎—‏ ‎это ‎примерно ‎55 ‎минут. ‎Но‏ ‎с ‎точки‏ ‎зрения‏ ‎внешнего ‎наблюдателя ‎восстановление‏ ‎базы ‎заняло‏ ‎больше ‎двух ‎часов! ‎Получается,‏ ‎что‏ ‎55 ‎минут‏ ‎сервер ‎занимался‏ ‎непосредственно ‎восстановлением ‎БД, ‎а ‎ещё‏ ‎час‏ ‎двадцать ‎занимался‏ ‎неизвестно ‎чем.

На‏ ‎самом ‎деле ‎это ‎время ‎сервер‏ ‎потратил‏ ‎на‏ ‎выделение ‎места‏ ‎под ‎восстанавливаемую‏ ‎базу. ‎Сложно‏ ‎поверить,‏ ‎но ‎это‏ ‎заняло ‎в ‎полтора ‎раза ‎больше‏ ‎времени, ‎чем‏ ‎полезный‏ ‎процесс. ‎Вас ‎устраивает,‏ ‎что ‎КПД‏ ‎дисковой ‎подсистемы ‎при ‎восстановлении‏ ‎всего‏ ‎40%?

Если ‎нет,‏ ‎то ‎давайте‏ ‎зайдём ‎в ‎локальную ‎политику ‎безопасности‏ ‎и‏ ‎предоставим ‎учётной‏ ‎записи, ‎под‏ ‎которой ‎работает ‎SQL ‎Server ‎разрешение‏ ‎«выполнение‏ ‎задач‏ ‎по ‎обслуживанию‏ ‎томов» ‎(в‏ ‎английской ‎версии‏ ‎—‏ ‎«perform ‎volume‏ ‎maintenance ‎tasks»). ‎Чтобы ‎это ‎подействовало‏ ‎необходимо ‎перезапустить‏ ‎службу‏ ‎SQL ‎Server. ‎Теперь‏ ‎сервер ‎сможет‏ ‎гораздо ‎быстрее ‎выделять ‎место‏ ‎на‏ ‎диске ‎для‏ ‎резервных ‎копий,‏ ‎восстановления ‎баз, ‎а ‎также ‎при‏ ‎расширении‏ ‎файлов ‎баз‏ ‎и ‎журналов.

Повторим‏ ‎эксперимент ‎с ‎восстановлением ‎стогигабайтной ‎базы:

Теперь‏ ‎база‏ ‎действительно‏ ‎восстанавливается ‎за‏ ‎55 ‎минут‏ ‎— ‎это‏ ‎почти‏ ‎в ‎два‏ ‎с ‎половиной ‎раза ‎быстрее, ‎чем‏ ‎при ‎настройках‏ ‎по‏ ‎умолчанию!

Читать: 1+ мин
logo Фёдор Самородов

Как программно обработать выдачу сервисных команд DBCC

Администраторы ‎баз‏ ‎данных ‎часто ‎используют ‎сервисные ‎команды‏ ‎DBCC. ‎Но‏ ‎это‏ ‎именно ‎команды, ‎а‏ ‎не ‎функции‏ ‎и ‎не ‎процедуры. ‎И‏ ‎в‏ ‎инструкции ‎SELECT‏ ‎их ‎использовать‏ ‎не ‎получится. ‎Так ‎как ‎же‏ ‎получить‏ ‎программным ‎путём‏ ‎доступ ‎к‏ ‎результатам ‎выполнения ‎этих ‎команд ‎(например,‏ ‎для‏ ‎сценариев‏ ‎автоматизации ‎обслуживания‏ ‎базы ‎данных)?

Попробуйте‏ ‎вот ‎такую‏ ‎двухходовую‏ ‎комбинацию.

Во-первых, ‎нужно‏ ‎добиться, ‎чтобы ‎используемая ‎команда ‎DBCC‏ ‎выдавала ‎результат‏ ‎в‏ ‎виде ‎одной ‎таблицы.‏ ‎Некоторые ‎вызовы‏ ‎DBCC ‎таблиц ‎вообще ‎не‏ ‎выдают,‏ ‎некоторые ‎выдают‏ ‎их ‎сразу‏ ‎несколько. ‎Тут ‎придётся ‎посмотреть ‎документацию,‏ ‎так‏ ‎как ‎поведение‏ ‎разных ‎DBCC-команд‏ ‎настраивается ‎по-разному.

Например, ‎для ‎SHOWCONTIG ‎нужно‏ ‎добавить‏ ‎опцию‏ ‎TABLERESULTS:

А ‎команду‏ ‎DBCC ‎SHOW_STATISTICS‏ ‎придётся ‎разбить‏ ‎на‏ ‎три ‎вызова:

Во-вторых,‏ ‎нужно ‎сделать ‎вызов ‎DBCC ‎динамическим‏ ‎и ‎тогда‏ ‎вы‏ ‎сможете ‎поместить ‎его‏ ‎результат ‎в‏ ‎таблицу ‎при ‎помощи ‎конструкции‏ ‎INSERT…EXECUTE,‏ ‎вот ‎так:


Читать: 2+ мин
logo Фёдор Самородов

Позаботьтесь о журналах SQL-сервера и SQL-агента

Настоящие ‎администраторы‏ ‎баз ‎данных ‎оптимизируют ‎всё, ‎что‏ ‎встретится ‎им‏ ‎на‏ ‎пути! ‎SQL-запросы, ‎настройки‏ ‎СУБД, ‎дисковую‏ ‎подсистему… ‎И ‎даже ‎журнал‏ ‎ошибок‏ ‎поддаётся ‎(и‏ ‎нуждается) ‎в‏ ‎оптимизации.

SQL ‎Server ‎ведёт ‎журнал ‎ошибок,‏ ‎сохраняя‏ ‎его ‎в‏ ‎файле. ‎При‏ ‎каждом ‎перезапуске ‎сервер ‎создаёт ‎новый‏ ‎файл‏ ‎для‏ ‎журнала, ‎а‏ ‎старый ‎переименовывает.‏ ‎Вот ‎так‏ ‎выглядит‏ ‎этот ‎журнал‏ ‎в ‎студии ‎и ‎в ‎проводнике:

Знакомая‏ ‎картина?

Небольшая ‎проблема‏ ‎подстерегает‏ ‎администраторов ‎боевых ‎серверов,‏ ‎которые ‎продолжительное‏ ‎время ‎работают ‎без ‎перезагрузки‏ ‎и,‏ ‎разумеется, ‎генерируют‏ ‎при ‎этом‏ ‎большое ‎количество ‎событий.

Если ‎вы ‎попытаетесь‏ ‎открыть‏ ‎большой ‎файл‏ ‎журнала ‎в‏ ‎студии, ‎то ‎вам ‎придётся ‎довольно‏ ‎долго‏ ‎ждать,‏ ‎пока ‎он‏ ‎весь ‎загрузится.‏ ‎А ‎если‏ ‎в‏ ‎процессе ‎ожидания‏ ‎вы ‎заглянете ‎на ‎график ‎расхода‏ ‎памяти ‎в‏ ‎диспетчере‏ ‎задач, ‎то ‎увидите,‏ ‎что ‎память‏ ‎расходуется ‎пугающими ‎темпами!

Но ‎не‏ ‎будем‏ ‎же ‎мы‏ ‎ради ‎инициализации‏ ‎нового ‎файла ‎журнала ‎перезапускать ‎SQL-сервер?!‏ ‎Конечно,‏ ‎это ‎делать‏ ‎не ‎обязательно,‏ ‎потому ‎что ‎имеется ‎специальная ‎хранимая‏ ‎процедура‏ ‎sp_Cycle_ErrorLog:

Она‏ ‎переключает ‎ведение‏ ‎журнала ‎на‏ ‎новый ‎файл.‏ ‎Для‏ ‎журнала ‎SQL-агента‏ ‎имеется ‎аналогичная ‎процедура ‎sp_Cycle_Agent_ErrorLog:

Эти ‎процедуры‏ ‎полезно ‎запускать‏ ‎автоматически‏ ‎по ‎расписанию, ‎чтобы‏ ‎сервер ‎не‏ ‎накапливал ‎чрезмерно ‎больших ‎файлов‏ ‎с‏ ‎журналами. ‎Чем‏ ‎меньше ‎будут‏ ‎эти ‎файлы, ‎тем ‎легче ‎потом‏ ‎будет‏ ‎найти ‎в‏ ‎них ‎нужные‏ ‎события.


Читать: 4+ мин
logo Фёдор Самородов

Как правильно обновлять SQL Server

Легко ‎и‏ ‎удобно ‎обновлять ‎Windows ‎— ‎для‏ ‎этого ‎есть‏ ‎механизм‏ ‎автоматического ‎обновления. ‎А‏ ‎для ‎SQL-сервера‏ ‎такого ‎автообновления ‎нет. ‎Но‏ ‎зато‏ ‎есть ‎инструмент‏ ‎для ‎работы‏ ‎с ‎обновлениями ‎в ‎ручном ‎режиме.

Что,‏ ‎если‏ ‎я ‎спрошу:‏ ‎«Все ‎ли‏ ‎обновления ‎установлены ‎на ‎ваш ‎SQL‏ ‎Server?»

Как‏ ‎ответить‏ ‎на ‎такой‏ ‎вопрос? ‎Заглянуть‏ ‎в ‎центр‏ ‎обновления‏ ‎Windows? ‎Это‏ ‎вряд ‎ли ‎поможет. ‎Скорее ‎всего‏ ‎вы ‎увидите‏ ‎там‏ ‎вот ‎такую ‎картину:

Но,‏ ‎как ‎ни‏ ‎странно, ‎это ‎вовсе ‎не‏ ‎означает,‏ ‎что ‎на‏ ‎SQL ‎Server‏ ‎установлены ‎самые ‎свежие ‎обновления!

Для ‎отслеживания‏ ‎обновлений‏ ‎именно ‎для‏ ‎SQL-сервера ‎Микрософт‏ ‎создал ‎специальную ‎страничку ‎— ‎Update‏ ‎Center‏ ‎for‏ ‎Microsoft ‎SQL‏ ‎Server. Положите ‎её‏ ‎себе ‎в‏ ‎закладки:

Но‏ ‎прежде ‎чем‏ ‎идти ‎туда, ‎необходимо ‎выяснить, ‎какая‏ ‎версия ‎установлена‏ ‎у‏ ‎нас ‎прямо ‎сейчас.‏ ‎Нам ‎нужен‏ ‎точный ‎номер, ‎включающий ‎в‏ ‎себя‏ ‎номер ‎построения‏ ‎(build ‎number).‏ ‎Получить ‎его ‎можно ‎посмотрев ‎на‏ ‎системную‏ ‎переменную ‎@@Version:

Запомните‏ ‎эти ‎цифры‏ ‎— ‎только ‎по ‎ним ‎мы‏ ‎сможем‏ ‎определить‏ ‎какие ‎обновления‏ ‎у ‎нас‏ ‎уже ‎установлены,‏ ‎а‏ ‎какие ‎—‏ ‎нет. ‎SQL-сервер, ‎в ‎отличие ‎от‏ ‎операционной ‎системы‏ ‎сам‏ ‎не ‎сообщает ‎нам‏ ‎о ‎каждом‏ ‎установленном ‎обновлении. ‎Поэтому ‎придётся‏ ‎работать‏ ‎с ‎номером‏ ‎@@Version.

Теперь ‎заходим‏ ‎в ‎центр ‎обновления ‎SQL-сервера ‎и‏ ‎видим‏ ‎там ‎удобную‏ ‎табличку:

Первым ‎делом‏ ‎заходим ‎по ‎ссылке ‎на ‎последнее‏ ‎накопительное‏ ‎обновление.

Здесь‏ ‎нам ‎понадобятся‏ ‎три ‎вещи:

  • Во-первых,‏ ‎запомним ‎номер‏ ‎построения,‏ ‎соответствующий ‎этому‏ ‎обновлению. ‎По ‎окончании ‎процедуры ‎обновления‏ ‎@@Version нашего ‎SQL-сервера‏ ‎должна‏ ‎выдавать ‎именно ‎такой‏ ‎номер.
  • Во-вторых, ‎обязательно‏ ‎следует ‎посмотреть ‎историю ‎номеров‏ ‎построений,‏ ‎соответствующих ‎обновлениям‏ ‎с ‎последнего‏ ‎сервисного ‎пакета. ‎Это ‎важно, ‎потому‏ ‎что‏ ‎накопительное ‎обновление‏ ‎установится ‎только‏ ‎на ‎предшествующий ‎ему ‎сервисный ‎пакет.
  • И‏ ‎в-третьих,‏ ‎полезно‏ ‎посмотреть ‎список‏ ‎исправлений, ‎содержащихся‏ ‎в ‎накопительном‏ ‎пакете.‏ ‎Администратор ‎должен‏ ‎быть ‎в ‎курсе ‎изменений, ‎вносимых‏ ‎этим ‎пакетом.

Посмотрев‏ ‎номера‏ ‎построений ‎предшествующих ‎обновлений,‏ ‎мы ‎увидим,‏ ‎что ‎разрыв ‎в ‎номерах‏ ‎по‏ ‎сравнению ‎с‏ ‎нашей ‎текущей‏ ‎версией ‎подозрительно ‎большой:

Это ‎из-за ‎того,‏ ‎что‏ ‎у ‎нас‏ ‎не ‎установлен‏ ‎сервисный ‎пакет ‎SP1. ‎Придётся ‎сначала‏ ‎поставить‏ ‎его.

И‏ ‎вот ‎теперь‏ ‎у ‎нас‏ ‎есть ‎план‏ ‎действий:

  1. Устанавливаем‏ ‎сервисный ‎пакет‏ ‎SP1.
  2. Устанавливаем ‎накопительный ‎пакет ‎обновлений ‎CU4.

Действуем!‏ ‎После ‎установки‏ ‎SP1‏ ‎проверяем ‎номер ‎@@Version. С‏ ‎исходного ‎2100.60‏ ‎он ‎увеличился ‎до ‎3000.0:

Теперь,‏ ‎сразу‏ ‎после ‎установки‏ ‎SP1 ‎устанавливаем‏ ‎CU4 ‎и ‎снова ‎проверяем ‎номер‏ ‎@@Version. Теперь‏ ‎этот ‎номер‏ ‎совпадает ‎с‏ ‎заявленным ‎в ‎описании ‎CU4:

Всё. ‎SQL-сервер‏ ‎успешно‏ ‎обновлён.‏ ‎Теперь ‎мы‏ ‎можем ‎ответить‏ ‎на ‎вопрос‏ ‎из‏ ‎первого ‎абзаца:‏ ‎«Да, ‎у ‎нас ‎установлены ‎все‏ ‎обновления ‎для‏ ‎SQL-сервера.»

Читать: 3+ мин
logo Фёдор Самородов

Оцените риски перехода на следующую версию SQL-сервера

Для ‎разработчиков‏ ‎переход ‎на ‎новую ‎версию ‎SQL-сервера‏ ‎— ‎событие,‏ ‎как‏ ‎правило, ‎радостное. ‎А‏ ‎вот ‎для‏ ‎администраторов…

Для ‎администратора ‎перенос ‎базы‏ ‎данных‏ ‎на ‎новую‏ ‎версию ‎SQL-сервера‏ ‎— ‎дело ‎рискованное. ‎А ‎вдруг‏ ‎в‏ ‎базе ‎используются‏ ‎какие-то ‎устаревшие‏ ‎механизмы, ‎которые ‎уже ‎не ‎работают‏ ‎в‏ ‎новых‏ ‎версиях?

Внести ‎определённость‏ ‎в ‎этот‏ ‎процесс ‎поможет‏ ‎специальный‏ ‎счётчик ‎производительности‏ ‎SQLServer: ‎Deprecated ‎Features. Левая ‎часть ‎названия‏ ‎этого ‎счётчика‏ ‎(до‏ ‎двоеточия) ‎зависит ‎от‏ ‎названия ‎установленного‏ ‎экземпляра ‎SQL-сервера ‎и ‎может‏ ‎выглядеть‏ ‎по-другому.

Экземпляры ‎этого‏ ‎счётчика ‎соответствуют‏ ‎устаревшим ‎функциям, ‎а ‎их ‎числовые‏ ‎показания‏ ‎— ‎количеству‏ ‎вызовов ‎этих‏ ‎функций ‎с ‎момента ‎последнего ‎запуска‏ ‎службы‏ ‎SQL‏ ‎Server.

В ‎интерфейсе‏ ‎системного ‎монитора‏ ‎не ‎очень‏ ‎удобно‏ ‎отслеживать ‎вызовы‏ ‎каждой ‎функции ‎по ‎отдельности, ‎проще‏ ‎оценить ‎происходящее,‏ ‎воспользовавшись‏ ‎SQL-представлением ‎этих ‎счётчиков.‏ ‎Так ‎мы‏ ‎сразу ‎увидим ‎всю ‎картину:

Скорее‏ ‎всего,‏ ‎выполнив ‎такой‏ ‎запрос ‎на‏ ‎своём ‎сервере, ‎вы ‎увидите ‎довольно‏ ‎большое‏ ‎количество ‎использований‏ ‎устаревших ‎механизмов.‏ ‎Но ‎далеко ‎не ‎всегда ‎это‏ ‎является‏ ‎препятствием‏ ‎для ‎модернизации‏ ‎SQL-сервера. ‎Микрософт‏ ‎делит ‎устаревшие‏ ‎функции‏ ‎на ‎две‏ ‎категории: ‎те, ‎которые ‎перестанут ‎работать‏ ‎уже ‎в‏ ‎следующей‏ ‎версии ‎SQL-сервера ‎и‏ ‎те, ‎которые‏ ‎отключатся ‎когда-нибудь ‎в ‎далёком‏ ‎будущем.

Так‏ ‎что ‎алгоритм‏ ‎наших ‎действий‏ ‎таков: ‎сначала ‎смотрим ‎на ‎содержимое‏ ‎http://Sys.DM_OS_Performance_Counters по‏ ‎счётчику ‎SQLServer:‏ ‎Deprecated ‎Features. Видим,‏ ‎к ‎примеру, ‎такую ‎картину:

Далее ‎открываем‏ ‎в‏ ‎документации‏ ‎раздел ‎Deprecated‏ ‎features (или ‎Устаревшие‏ ‎функции в ‎русской‏ ‎версии).‏ ‎Ищем ‎там‏ ‎функцию, ‎совпадающую ‎по ‎названию ‎с‏ ‎экземпляром ‎сработавшего‏ ‎счётчика:

И,‏ ‎если ‎находим ‎устаревший‏ ‎механизм ‎в‏ ‎первой ‎части ‎списка ‎(значит,‏ ‎это‏ ‎перестанет ‎работать‏ ‎уже ‎в‏ ‎следующей ‎версии), ‎прикидываем, ‎как ‎избавиться‏ ‎от‏ ‎этой ‎зависимости:

Обратите‏ ‎внимание, ‎что‏ ‎счётчики ‎работают ‎для ‎всего ‎сервера,‏ ‎а‏ ‎не‏ ‎для ‎отдельной‏ ‎базы! ‎Так‏ ‎что ‎на‏ ‎практике‏ ‎придётся ‎дополнительно‏ ‎озадачиться ‎вопросом, ‎в ‎каких ‎именно‏ ‎базах ‎данных‏ ‎используются‏ ‎устаревшие ‎механизмы.

Показать еще

Подарить подписку

Будет создан код, который позволит адресату получить бесплатный для него доступ на определённый уровень подписки.

Оплата за этого пользователя будет списываться с вашей карты вплоть до отмены подписки. Код может быть показан на экране или отправлен по почте вместе с инструкцией.

Будет создан код, который позволит адресату получить сумму на баланс.

Разово будет списана указанная сумма и зачислена на баланс пользователя, воспользовавшегося данным промокодом.

Добавить карту
0/2048