суббота, 16 ноября 2013 г.

SQL-скрипты для поиска данных

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

Поиск объектов во всех базах данных сервера

У вас бывало, что нужно найти таблицу чтобы посмотреть данные или структуру, а вы не помните точно в какой БД она находится? У меня, периодически, такое случается. Пример - найти таблицы из проекта пятилетней давности, чтобы посмотреть как тогда решал текущую задачу.

К счастью, есть процедура sp_MSforeachdb, которая позволяет написать такой скрипт довольно компактно:

DECLARE @name AS SYSNAME,
@strSQL AS VARCHAR(MAX)
SET @name = 'Hierarchy'

SET @strSQL = '
IF EXISTS(SELECT * FROM ?..sysobjects WHERE name LIKE '
'%'+@name+'%'')
BEGIN
SELECT '
'?'' db, name FROM ?..sysobjects WHERE name LIKE ''%'+@name+'%''
END
'

CREATE TABLE #result(
db SYSNAME,
name SYSNAME,
PRIMARY KEY(db,name))

INSERT #result EXEC sp_MSforeachdb @strSQL
SELECT * FROM #result

DROP TABLE #result

Здесь всё достаточно просто:

  1. Задаём часть названия, по которому будем искать (в данном случае - Hierarchy).
  2. Собираем динамический SQL, который ищет по sysobjects (для некоторых старых версий MS SQL можно вместо VARCHAR(MAX) использовать VARCHAR(2000), например).
    При этом символ "?" заменится на название БД.
  3. С помощью конструкции INSERT ... EXEC сохраняем все результаты во временную таблицу, чтобы отобразить, в итоге, единый результат.

Поиск подстроки в текстах хранимых процедур

Как вы знаете, тексты хранимых процедур, триггеров и представлений можно найти в таблице syscomments.

Чтобы наш предыдущий запрос позволил нам найти упоминание в syscomments некоторой подстроки, его можно переписать следующим образом:

SET @strSQL = '
SELECT DISTINCT '
'?'' as db, o.name FROM [?].dbo.syscomments s
JOIN [?].dbo.sysobjects o ON o.id = s.id WHERE s.[text] LIKE '
'%'+@name+'%'''

Обратите внимание на DISTINCT - может пригодиться, потому что иногда для одного объекта бывает несколько записей в syscomments.

Поиск подстроки во всех строковых полях всех таблиц

Такой скрипт здорово помогает спать спокойно после "чистки" базы перед отправкой клиенту. Естественно, этой областью его применение не ограничивается.

Для этого случая помощник в виде процедуры от MS не нашёлся, поэтому пришлось использовать курсоры:

declare @pattern as nvarchar(MAX)
set @pattern = N'%Test%'
set nocount on
declare @sql as nvarchar(MAX)
declare @table as sysname
declare tables cursor local static read_only for select name from sys.tables t where t.is_ms_shipped = 0
open tables
fetch next from tables into @table
create table #results(name sysname not null, value nvarchar(MAX) not null)
while @@FETCH_STATUS = 0
begin
set @sql = ''
select @sql = @sql + '
insert into #results select '
'' + @table + '.' + name + ''' as name, [' + name + '] from [' + @table + '] where [' + name + '] like ''' + @pattern + ''''
from sys.columns c where c.object_id = OBJECT_ID(@table) and c.system_type_id in
(select system_type_id from sys.types where collation_name is not null)
exec(@sql)
fetch next from tables into @table
end
select * from #results
close tables
drop table #results

Помимо курсоров принципы те же. Есть пара нюансов:

  • Ищем таблицы без флага is_ms_shipped, чтобы просматривать только таблицы, созданные на этапе разработки.
  • Для отбора строковых столбцов вместо списка типов (который поддерживать утомительно) используется фильтр "collation_name is not null".

Резюме

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

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

Если у вас есть замечания, пожелания или новые темы – пишите в комментариях, твиттер или на olegaxenow.reformal.ru. Постараюсь учесть.

среда, 8 февраля 2012 г.

Разработка пакетов NuGet + инфраструктура

В статье "Model scaffolding для MVC 3 – идеи и принципы" я рассказал об идеях и принципах, заложенных в основу пакета Model Scaffolding. Сейчас я расскажу о следующем:

  • Как написать простой пакет NuGet.
  • Как подготовить инфраструктуру для разработки и отладки пакетов NuGet.
  • Как начать реализовывать свой Scaffolder (генератор чего-либо в любом вашем проекте, необязательно ASP.NET MVC).

Важное замечание: после выхода NuGet 1.6 вы можете столкнуться с неожиданными ошибками при установке любых пакетов NuGet для Scaffolding (мои пакеты зависят от T4Scaffolding). В этом случае рекомендую такую последовательность:

  • Uninstall NuGet.
  • Install NuGet.
  • Затем то же самое для всех Scaffolding-пакетов (с учетом зависимостей некоторые установятся сами).

NuGet

Scaffolder имеет смысл делать именно NuGet-пакетом, поэтому коротко расскажу о том что это и как создать и опубликовать пакет в простом случае (подробнее можно почитать в документации). Про возможности NuGet я уже рассказывал раньше, в статье MVC 3 + scaffolding.

NuGet-пакет формируется из набора файлов с помощью файла спецификации и приложения NuGet.exe. Затем его можно опубликовать на NuGet.org или на другом (например, своем) сервере. Также можно просто скопировать в некоторую папку, а папку добавить в настройки Visual Studio (Tools / Library Package Manager / Package Manager Settings). Так что, если хотите использовать возможности NuGet в своей закрытой разработке – это тоже возможно.

воскресенье, 15 января 2012 г.

Code First Migrations + Entity Framework 4.3 Beta 1

MonarchButterflyНа днях, а точнее 12 января увидел свет Entity Framework 4.3 Beta 1. Основная тема этого релиза – EF Code First Migrations. Помимо этого, есть несколько изменений, которые тоже имеет смысл упомянуть.

На фото миграция бабочки монарх (CC BY-NC-ND 2.0, оригинал здесь).

В этой статье я, со своей точки зрения, разумеется, отвечу на вопросы, подкрепляя их примерами:

  • Что такое миграции и для чего они нужны?
  • Что интересного в этом релизе и в EF Code First Migrations вообще?

Думаю, вряд ли кто-то использует миграции в повседневной коммерческой разработке. Поэтому я не буду явно выделять список нововведений, а буду просто рассказывать про миграции, отдельно выделяя новое в EF 4.3 Beta 1.

Кстати, наверное вам будет интересно, что релиз EF 4.3 планируется на первый квартал этого года. Жаль только что релиз EF 5.0 с поддержкой enum и оптимизированной скоростью ждёт наc нескоро – с выходом .NET 4.5 ожидается только EF 5.0 Beta 1.

Краткое описание миграций

Миграции в EF предназначены для решения проблемы изменения структуры базы данных в процессе эволюции приложения. Один из вариантов решения этой проблемы я озвучивал ранее в статье “Основы SQL - DDL и рефакторинг БД”. Надеюсь, что когда будет готов EF Code First Migrations, он будет значительно лучше, чем подход со скриптами.

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

понедельник, 9 января 2012 г.

Code Metrics + Refactoring

MicroscopeДумаю, большинство из вас знают, что в Visual Studio есть набор метрик кода. Моя цель – привлечь к ним ваше внимание, в том числе как к одной из отправных точек для ревью кода и рефакторинга.

Сначала я расскажу о запуске подсчёта метрик. Потом кратко опишу каждую метрику и дам некоторые рекомендации по рефакторингу в случае проблем. Затем немного расскажу о моём опыте использования метрик на практике.

Однако, начиная разговор о метриках кода в Visual Studio, хочу пояснить моё отношение к метрикам кода вообще.

С одной стороны, это мощный инструмент для оценки качества кода. По моему мнению, его обязательно стоит использовать как отправную точку для ревью кода (в том случае, когда идем не от коммита, а делаем ревью отдельного класса/модуля).

С другой стороны, не стоит идеализировать метрики кода – это всего лишь один из инструментов. Вы же не считаете, что раз молоток хорошо забивает гвозди, это лучшее средство для закручивания шурупов? ;)

воскресенье, 8 января 2012 г.

Productivity Power Tools

Если говорить о Productivity Power Tools нейтральным тоном, то это плагин к Visual Studio, который можно бесплатно загрузить с Visual Studio Gallery. Там же вы найдёте его описание на английском языке. Картинка оттуда же и хотя выглядит странно, однако, метафорически, так и есть – это не что иное как возможность “подкрутить” студию чтобы работать с ней было еще немного удобнее.

Скажу сразу, весь набор возможностей (см. описание по ссылке выше) вам вряд ли понадобится. Однако одно я могу сказать наверняка – если вы используете студию без других дополнительных средств для навигации по коду и рефакторинга, то я очень удивлён, что вы читаете эти строки не закончив чтение на заголовке со словами “что о нём читать, и так всё знаю” :)

Поэтому обладателям “чистой студии” рекомендую как минимум скачать этот плагин и попробовать. В результате наверняка пригодятся практически все предоставляемые возможности.

Тем же, кто использует ReSharper и его альтернативы, вероятно будет интересно узнать, чем же меня “купил” плагин Productivity Power Tools. Сначала расскажу о двух “фишках” которые будут полезны многим, а потом о той, специфической, которая сильно повысила комфортность работы лично для меня. А в конце немного о других возможностях.

воскресенье, 18 декабря 2011 г.

Отладка сессии ASP.NET

CrashTestDummyНа этот раз, как и обещал в статье “Сессия ASP.NET и проблема с параллельными запросами”, я расскажу, как можно отладить обращения к сессии с помощью нестандартного провайдера.

А в завершение, в качестве бонуса, расскажу забавные подробности про режим ReadOnly, который иногда не совсем ReadOnly…

Для чего может потребоваться логгирование обращений к сессии? На мой взгляд, наиболее подходящими являются два сценария:

  • “Нужно ускорить некоторые страницы нашего приложения, давайте посмотрим где используется сессия и нужна ли там запись в сессию или сессия вообще.”
  • “Для того, чтобы не блокировать конкурентные запросы в рамках одной сессии, давайте прогоним все наши сценарии и проанализируем обращения к сессии.”

воскресенье, 27 ноября 2011 г.

Сессия ASP.NET и проблема с параллельными запросами

Эта статья будет интересна прежде всего тем, кто, явно или неявно, использует сессию ASP.NET в своих приложениях. Тем же, кто принципиально не использует сессию, можно почитать для общего развития – вдруг пригодится на будущее.
mcdonalds_queue
И, поверьте мне, она будет невероятно интересна разработчикам таких приложений, которые могут обрабатывать несколько небыстрых одновременных запросов от одного пользователя. Показательный пример – одновременное скачивание нескольких больших файлов. Это реальная проблема, с которой столкнулись мои коллеги и на отладку которой было потрачено неадекватно много времени.

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

В принципе, ситуация с конкурентными запросами в рамках одной сессии описана в статье MSDN ASP.NET Session State Overview. Но есть нюансы. Во-первых, это один неприметный абзац в конце статьи (вместо выделенного блока в начале). Во-вторых, MSDN не раскрывает многих неочевидных моментов. И, что важно, ни один из моих знакомых ASP.NET разработчиков не знал об этой особенности.

Заинтересовались? Тогда продолжаем. Я сформулирую несколько правил работы сессии и покажу на примере, что они верны.

четверг, 13 октября 2011 г.

ASP.NET MVC MiniProfiler

Всем доброго времени суток. Сегодня я хочу рассказать про ASP.NET MVC MiniProfiler. А первое, что я хочу рассказать, это то, что, вопреки распространённому мнению и названию, этот профайлер вполне можно применять для отладки обычных (не MVC) ASP.NET приложений. Дальше я на примере покажу как это сделать. А пока обо всем по порядку.

Что такое MiniProfiler?

Это способ отладить ASP.NET-приложение на production (или, если вам больше нравится, “приложение, находящееся в промышленной эксплуатации”). И, что важно, не сильно влияя на производительность (то, что это работает на сайтах платформы StackExchange как бы намекает).

Вкратце процесс подключения выглядит так:

  1. Добавляется ссылка на dll.
  2. Подключается в “Master Page” или любое другое подходящее место одна строчка по инициализации UI.
  3. В Global.asax.cs прописываются вызовы по старту и остановке профайлера.
  4. Либо добавляются вызовы Step(string) там, где вам интересно, либо “сбоку” добавляются фильтры (вроде ProfilingActionFilter), чтобы не модифицировать код.

Опять же вкратце, на выходе получаем в виде небольшой разворачивающейся “закладки” на странице следующие возможности:

  • Суммарное время.
  • Время на дочерние действия (пункт 4) и запросы к БД.
  • Показать/скрыть “тривиальные” запросы (с маленькими затратами времени).
  • Переслать ссылку на отчет (данные хранятся в кэше).

Заинтересовались? Тогда продолжим…