Разработчикам систем, использующих базы данных, приходится много писать на языке SQL. Все знают, но не все это осознают, что SQL переживает уже четвертый десяток лет как одна из самых успешных и широко распространенных технологий в мире компьютеров. Технологии не стоят на месте, но даже сегодня, многие создатели пост-реляционных систем баз данных специально вкладывают средства и ресурсы для предоставления пользователям SQL-подобных средств поиска и манипуляции данных. Давайте рассмотрим, как современные требования к продуктам для разработки БД облегчают и ускоряют создание корректного кода на SQL и познакомимся с любопытным маленьким трюком.
Недавно наткнулся на простое и эффективное решение одной элементарной даже не проблемы, а неудобства и решил поделиться. Суть вот в чем:
Как и любой практикующий разработчик SQL или администратор БД, я сохраняю скрипты для решения повторяющихся задач, чтобы в будущем уже иметь подготовленный инструмент для быстрого выполнения. С помощью DBArtisan можно автоматически записывать все операторы SQL, которые я выполнял в течение сессии и потом использовать некоторые из них для создания и сохранения таких скриптов. В среде DBArtisan я могу поместить в главное меню пункты для вызова наиболее часто используемых скриптов или одновременно выполнить скрипт на нескольких серверах.
Естественно, многие из таких повторяющихся задач требуют различных специализированных «кусков кода», в зависимости от решаемой задачи или БД. Оказалось, что часто быстрее и проще в поддержке не создавать множество однотипных, «почти» совпадающих скриптов SQL или версий, а применять «блочные комментарии» для временного выключения/включения нужного фрагмента SQL и вручную управлять ими в ISQL редакторе.
Все знают, что стандартом SQL предусмотрены 2 типа комментариев в исходных текстах:
- «Строчные», которые начинаются с символов ‘— ‘, и превращают все до конца этой строки в текст, который транслятор SQL не воспринимает. При переходе на следующую строку этот комментарий уже не действует
- «Блочные», которыми можно превратить в комментарий большой блок SQL -кода. Они начинаются с комбинации символов ‘/*’ и заканчиваются, как только встретится комбинация ‘*/’. Эти символы обозначают «начало блока» и «конец блока»
Трюк, на примере которого я расскажу о возможностях современных ISQL-редакторов, предложил Peter Zerk — один из известных специалистов по MS SQL Server. Возьмем текст SQL с закомментированным куском:
while (@j < @nstr) begin -- цикл по строкам массивов INSERT INTO PRR.TRANSITADVOLS ( VAL_ID,VAL_MASH ) VALUES /* здесь может быть блок любого текста произвольной длины, который не будет выполняться сервером, ... ... обратите внимание на "строчный" синтаксис комментария в начале следующей строки --*/ (@USERNM,@BDATE);
Казалось бы, ничего не изменилось, но помещение «конца блока» в «строчном» комментарии дает нам возможность для активации всего этого блока (когда мы решим, что нам нужно его выполнить) не искать и удалять как начало, так и конец блока, а просто поставить символы ‘—‘ перед комбинацией «начало блока»
/*
выключенный блок
исходного текста
--*/
--/*
включенный блок
исходного текста
--*/
Если бы мы не поместили «конец блока» внутрь строчного комментария, выполнение скрипта было бы прекращено, и мы получили бы ошибку Incorrect syntax near ‘*’
Остается только удивляться, почему мы с коллегами, в свое время, прошли мимо этого решения.
Теперь мы можем локализовать похожие, но специфические куски кода в одном месте, управлять своим кодом.
-- Блоки помогают управлять спецификой аналогичного кода /* --SCRIPT 'A' - ЭТА ЧАСТЬ используется для вх. дат в формате mm/dd/yyyy ... .. сюда поместите код для поддержки дат в формате mm/dd/yyyy ... --*/ /* -- SCRIPT 'B' - ЭТА ЧАСТЬ используется для вх. дат в формате dd/mm/yyyy ... .. сюда поместите код для поддержки дат в формате dd/mm/yyyy ... --*/
Допустим, мне нужно обработать входные данные с датами в «американском» формате — ‘mm/dd/yyyy’. Я вставляю символы — перед первой группой «начало блока» и включается выполнение блока SCRIPT A. При этом — SCRIPT B остается выключенным. Если поступили данные с датой в «нашем» формате — dd/mm/yyyy — то поступаю наоборот, ставлю — перед вторым «началом блока», и включается блок SCRIPT B
Трассировка
При помощи этого же трюка T-SQL позволяет нам использовать еще один полезный «побочный эффект».
-- Сообщите при помощи PRINT, какой блок текста активен --/* --SCRIPT 'A' - ЭТА ЧАСТЬ используется для целых данных Print 'Script A active - integer data' --*/ Print 'Script A inactive /* -- SCRIPT 'B' - ЭТА ЧАСТЬ используется для символьных Print 'Script B active - char data' --*/ Print 'Script B inactive'
В окне сообщений появится трассировка:
И все это достигается путем комментирования одной строки исходного текста.
Отладка
Случалось ли вам разбираться, почему запрос со сложным набором условий отбора работает совсем не так, как ожидалось?
Теперь это сделать проще, путем поочередной проверки работоспособности всех или части этих условий
SELECT * FROM #table /* -- Сложный набор условий с непроверенными результатами WHERE ID in ( SELECT something FROM a-really-complex-condition WHERE we-are-not-sure-what-we-get ) --*/ WHERE ID = 1 -- В работоспособности этого условия мы уже убедились
Или управлять глубиной модификации данных при выполнении скрипта
update #table set Comment = 'changed' where Comment = 'change me' /* -- use 'line comment' to enable UPDATE to proceed and 1 = 1 --*/ and 1 = 0
Этот пример позволяет мне отлаживать весь скрипт без выполнения модификации на самом деле до тех пор, пока я не проверю, что все работает, как следует.
И последнее.
Уважаемый автор привел пример использования этого трюка для поддержки вложенных одного в другой блоков комментариев.
SELECT * FROM Mytable WHERE 1 = 1 -- always true /* -- first condition to check AND condition1 = TRUE --*/ /* -- some more conditions AND condition2 = ( SELECT condition3 FROM Myanothertable WHERE 1 = 1 /* -- Paying attention? This is a nested Comment Block AND NestedCondition = TRUE --*/ ) --*/ --/* the comment here ‘activates' this condition. It gets checked. AND Comment = 'buggy value' --*/
Вы можете убедиться сами, это действительно работает. В любом ISQL редакторе, например, запустите DBArtisan, и скопируйте туда этот текст.
SQL — это универсальный, если можно так сказать, стандартизированный язык, который, тем не менее, в каждой СУБД преображается в соответствии с требованиями, предъявляемыми к нему создателями данной платформы. В MS SQL — это диалект T-SQL, в Oracle мы применяем PL/SQL, в прочих платформах — вносятся свои уникальные особенности синтаксиса и поведения. Вот как это выглядит для MS SQL:
Я решил применить понравившийся мне трюк для работы с Oracle. Можно дополнительно запустить поставляемые вместе с Oracle средства, но можно остаться в DBArtisan, который поддерживает одновременную работу с разными платформами СУБД.
В DBArtisan я открыл еще одно окно редактора SQL, указал, что этот редактор связан уже с БД Oracle и перенес в него скрипт из примера выше:
Я только вставил текст запроса. Видите красную отметку у строки 13?
Это автоматический синтаксис-анализатор DBArtisan сигнализирует, что SQL текст не соответствует правилам данного диалекта SQL. Проверка на сайте Oracle подтвердила, что, несмотря на графические синтаксические схемы в документации, Oracle «вложенные» комментарии не поддерживал и не поддерживает. Кстати, остальные примеры сработали!
Автоматический синтаксический анализатор/валидатор — это одна из трех составных частей, которые были включены в редактор SQL DBArtisan, в соответствии с современными требованиями для ускорения разработки программ на SQL и улучшения их качества. Также он обнаруживает случаи использования имен объектов, которые отсутствуют в БД, прямо по мере набора текста.
Еще очень помогает при разработке SQL программ, сильно ускоряет и позволяет избежать простейших ошибок написания режим Code Completion. Если вам приходилось писать на современных языках программирования в средах быстрой разработки приложений, например, Delphi или C++Builder, Java Designer или Eclipse, вы с ней знакомы: по мере набора текста, редактор сам подбирает подходящие по контексту объекты (не только синтаксические элементы) и подставляет их в текст за вас или предлагает сделать выбор из списка. DBArtisan подбирает объекты из текущего контекста исходя из платформы СУБД редактора, из списка реально существующих объектов схемы используемого источника данных.
Если при написании сложного кода на SQL вдруг выясняется, что необходимо внести какие-то изменения в другие объекты схемы, ну например, добавить входной параметр в хранимую процедуру, можно просто перейти к ее редактированию (в специализированном диалоговом редакторе), выделив ее имя прямо в тексте на SQL и вызвав при помощи мышки соответствующую Hyperlink Object Action.
Как и любой текст, скрипты программ на SQL можно создавать в любом текстовом редакторе. Но если вы профессионал, вы очень много и часто работаете с SQL, то вам уже не будет достаточно наличия подсветки синтаксиса и автоматического переформатирования кода, особенно, если вам приходится переключаться между различными платформами СУБД.
Более того, известны более-менее успешные попытки сделать технологии разработки серверной части информационных систем более гибкими, более приспособленными для внесения изменений и реализации новых требований, в большей степени использующими преимущества коллективной разработки и многократного применения удачных и проверенных решений. Уже достаточно давно многие СУБД и решения для разработчиков имеют возможность применять «версионность» текстов на SQL. Об этом — в следующих статьях.