Завершив в недавнем прошлом очередную доработку своей легковесной технологии SQL-файл, применяемой для эффективной трансляции файлового SQL-кода в базу данных, автор данной статьи решил в очередной раз представить (в этой заметке теперь, на популярном ресурсе) свои реализованные, хотя бы отчасти, идеи касательно программирования MSSQL, а так же некоторые соображения относительно применения SQL вообще. Автор полагает, что несмотря на форму предлагаемой им частной реализации SQL-файл (для MSSQL), лежащая в основе подхода концепция имеет определённую силу и смысл.

Введение

Язык SQL (его основа), а также средства поддержки SQL придумывались давно. Классические серверы реляционных БД, как правило, не допускают прямого размещения файлов исходного кода запросов на сервере; например, в специальных директориях БД, подобно тому, как, к примеру, на веб-сервере можно выложить JS, HTML, CSS и т. п. (В реляционной СУБД всё весьма консервативно, присутствует множество серьёзных ограничений.) Вместо этого клиент SQL-сервера имеет доступ к механизму манипулирования объектами БД и сервера (путём отправки пакетов инструкций SQL). С помощью специальной (как правило графической) консоли БД создаётся подобие редактирования исходников сохраняемых в БД объектов. Собираясь же по определённым причинам переходить (всецело) на файловую базу для хранения скриптов Вы можете обнаружить недостаточную поддержку работы с подобными файлами-скриптами со стороны клиентских инструментов разработки SQL. Представленная же здесь (в статье) легковесная технология SQL-файл ориентирована как раз на файловую базу для размещения исходников, в директориях и файлах SQL, для SQL-объектов БД: таблицы (скрипты их создания), индексы, ограничения (constraint), хранимые процедуры (ХП), функции и т. п.

Описывая в общих чертах и отдельных деталях конкретное исполнение идей, статья, в то же время, содержит элементы некоторого вымысла (фантастики), нацеленные на обретение теоретического видения касательно применения различных диалектов языка SQL, в плане предлагаемого общего знаменателя (для доступа к SQL-запросам), отражённого здесь путём привнесения соответствующих терминов: Заголовок SQL-запроса (формат, подлежащий унификации), Компилируемый временный запрос к SQL-серверу (допускает определённую унификацию) и прочее. Непривычный взгляд на взаимодействие с SQL-сервером позволяет, однако, не быть обязанным к общению с т. н. большой ORM (Object-Relational Mapping), иметь свободу интенсивно задействовать программирование внутри базы данных (функции, вспомогательные ХП и прочее), при этом логически разделяя запрос к веб-серверу на универсальные части-составляющие: (1) Составляющая SQL-сервера (условно открытый SQL-заголовок + реализация); (2) Составляющая веб-сервера (декларация API + имплементация); (3) Клиентская составляющая (в основном определения для использования запроса). Наличие разнородных сред и языков программирования для исполнения одного, казалось бы простого, запроса клиента создаёт препятствие для гладкой его реализации. Сложности же, вызываемые двойственной природой реализуемого запроса (SQL-сервер + веб-сервер) навряд ли подлежат существенному устранению, учитывая даже применение, так скажем, идеальной (максимальной) ORM.

В последующих текстах присутствует определённое количество специфических наименований, а так же сверхкоротких фрагментов из соответствующих скриптов и конфигурационных файлов (т. н. инишник-и, батч-и и т. п.). Можно особо не заострять на них внимание; они тут изобильно приводятся в основном с той целью, чтобы показать, что поведение т. н. SQL-трансляции (файлы => объекты SQL) подлежит конфигурированию, настраивается и доступно для управления. Так же, не следует ассоциировать применение файлового коммандер-а, процессора CMD и т. п. с какой бы то ни было отсталостью. Автономный проект (компиляция) SQL-файл, по ощущениям автора имеет, в каком-то смысле, схожие черты с автономными проектами в универсальной кроссплатформенной среде разработки VS-Code (конфигурирование, задачи, запуски и т. п.). Файловый же коммандер (здесь это, как правило, Far Manager) вкупе со сценариями обработки (здесь это в основном CMD) хорошо подходят для реализации автономного, независимого от привязок к фирменным IDE, компилируемого проекта.

Касательно же недостатков интеграции SQL-файл с Far Manager, стоит отметить отсутствие какой-либо функции автодополнения при редактировании SQL, в отличие, например, от задействования технологии IntelliSense в Visual Studio. В SQL-файл подобное редактирование (с “равнением” на коллекцию имён из базы данных в данном случае) доступно через т. н. IDE-стартер SSMS.cmd, что, однако, также имеет свои ограничения, выражающиеся, в первую очередь, в “замораживании” всего окружения (переменные среды) на моменте старта IDE (и не только это).

Минимальная формулировка назначения и замысла SQL-файл:

Когда-то, презентуя впервые свою методику взаимодействия с СУБД SQL Server, автор данной статьи писал (в прошлом) примерно следующее:

Добрый день, уважаемые разработчики SQL!

Позвольте представить Вашему вниманию самодельную легковесную технологию, именуемую как SQL-файл (или же SQL в файлах), — для MSSQL и T-SQL. Данная методика успешно применялась в течение достаточно долгого периода для программирования БД расчёта квартирной платы (город Воронеж). Технология базируются на известной утилите SQLCMD и командном процессоре CMD. В качестве IDE (командный пульт SQL + оперативный редактор) эффективно применяется Far Manager 3, со вспомогательными простейшим плагином и макросами. (Так же, возможно задействование других редакторов SQL, помимо встроенного в FAR.)

Идея состоит в том, чтобы поддерживать исходный код и/или вспомогательные скрипты в виде SQL-файлов в директориях, транслируя их в базу данных, по отдельности либо группами. Используя утилиту $SQLTRANS и соответствующие шаблоны, можно настроить трансляцию (генерацию) большого количества объектов БД, работающую, так сказать, на раз-два-три. За один приём, например, возможно обновить активную составляющую программы в базе (процедуры, функции, представления, …), или, скажем, создать табличную структуру (и наполнить её некоторым количеством необходимых данных). При умелом обращении подсистема (активные объекты) может вполне свободно корректироваться даже на работающей программе/службе.

Обзорное минимальное описание SQL-файл доступно на страницах Handicraft-CODE (англ. язык): https://handicraft.remelias.ru/sdk/sql_file.html (Handicraft-CODE :: Handicraft-SDK :: SQL-file technology); https://handicraft.remelias.ru/sdk/sql_tools.html (Handicraft-CODE :: Handicraft-SDK :: CMD-utilities :: SQL-tools).

А так же, см. скриншот-ы: https://handicraft.remelias.ru/sdk/sql/screenshots_1.html; https://handicraft.remelias.ru/sdk/sql/screenshots_2.html; https://handicraft.remelias.ru/sdk/sql/screenshots_3.html.

Вместе с командными утилитами и шаблонами предлагается возможное (опционально) использование так называемого Усиленного Transact-SQL, с препроцессором (на базе переменных среды), представленного множеством соответствующих импорт-определений и широким набором хелпер-объектов прилагаемой библиотеки SQLAUX (полезные программатик-и).

: : : : : : : : : :

Спасибо за внимание!

I. Предыстория (что не так с языком Transact-SQL, расширения SQLCMD и др.)

Автор данной статьи в течение долгого времени имел дело с СУБД MS SQL Server. Когда-то в прошлом к автору пришло осознание того, что режим исполнения инструкций (Control Flow) в языке Transact-SQL, который MSSQL предлагает по умолчанию (режим), не является надёжным. Без использования специальных блоков-обёрток для перехвата исключения — необходимо везде-везде проверять состояние последней ошибки @@ERROR. Исходя из желания использовать эффективный (полуавтоматический, с исключениями) контроль ошибок, а так же и по другим (тоже веским) причинам, в течение длительного времени вырабатывалась и применялась интересная технология SQL-файл, основанная на расширениях SQLCMD. SQL-код хранится в файлах, организованных специальным образом в виде SQL-проекта (в дереве вложенных файловых папок). Для трансляции файлов в базу данных применяется легковесный обработчик — препроцессор-конкатенатор скриптов: SqlCatPP (EXE) в связке с вызывающей его обёрткой $SqlTrans (CMD). Так же, подразумевается использование вспомогательной библиотеки элементарных хелпер-объектов и констант (вида $(<ПеременнаяСреды>)) SQLAUX (в приложение к основному транслятору/препроцессору). В качестве редактора SQL в настоящее время, помимо встроенного редактора Far Manager, а так же одного из GUI-редакторов для простого текста (см. в загрузках), доступно так же использование SQL Server Management Studio (+Environment), в немного ограниченном, однако, виде (см. устройство SSMS.cmd в загрузках).

II. Технология SQL-файл на страницах https://handicraft.remelias.ru/

Вот ссылки на страницы автора статьи (минимальное описание + картинки и примеры):

Ещё картинки (вспомогательное применение SQL-файл, бок-о-бок файлы SQL/C# и др.):

Так же, в авторском блог-е https://blog-hc.remelias.ru/, по SQL-файл присутствует серия заметок (хронологический порядок пост-ов):

II.1. Запуск SQL-файлов с учётом подготовленного окружения

После настройки, проведённой соответствующим образом, легковесных инструментов, появляется возможность “запускать” правильно сконфигурированные (снабжённые лежащим в том же каталоге $sql_settings.cmd) файлы кода с усиленным Transact SQL. В Far Manager подобная трансляция срабатывает (приводится в действие) из панели по <Enter> (для ассоциации SQL), из встроенного редактора по <Ctrl+Enter> (простейший макрос); в отдельном окне (запуск из панели) — по <Ctrl+PgDown>, в отдельном окне (запуск из встроенного редактора) — по <Ctrl+F12>. Утилита $SQLTRANS “подхватывает” $sql_settings.cmd; файлы из подкаталогов, как правило, наследуют (и, возможно, расширяют) сеттинг-и (окружение) более высокого уровня расположения. Корневой же $sql_settings.cmd подключает, как правило, SQLAUX.cmd (из каталога библиотеки), а так же @<имя_проекта>.cmd (в UTF-8). Запустив же SQL Server Management Studio посредством стартера SSMS.cmd (располагается в корне SQL-проекта), данный процесс так же получает возможность использовать все тонкости настроенного окружения:

  • Доступны слова для обёртки основного блока: $(BEGIN_AUX), $(END_AUX), с автоматической защитой от ошибки (т. н. “заворачивание” в begin try / end try / … и т. д.), которые, так же, инициализируют некоторые T-SQL-установки SET (при раскрытии $(BEGIN_AUX));

  • Многочисленные ключевые слова и константы: $(LOOP_AUX), $(TRUE_AUX), $(DropFunctionScript_AUX), $(num_IntStrMaxLength_AUX), $(dt_Name_AUX), и т. п.;

  • Ссылки на собственные переменные проекта $(<ИмяПеременной>).

Необходимо сначала должным образом установить и настроить поддержку SQL-файл!!!

  • При установленном плагин-е для Far Manager CmdCpAuto, появляется возможность комфортно просматривать (по F4) многочисленные CMD (с автоматическим переключением на нужную кодировку).

  • После прописывания в системе пути (PATH) к командным утилитам “…\HandicraftSDK\CMD-utilities” (папка с CMD, EXE) — становится работоспособным следующее: $sqltrans.cmd, $sqlupload.cmd, $sql.cmd, $sqlcon.cmd, $sqltocsvexp.cmd и прочие “$”-команды.

  • Так же, в системе потребуется определить путь к библиотеке скриптов и констант окружения SQLAUX: SQLAUX_ROOT = …\HandicraftSDK\SQL\SQLAUX.

  • При установленных макросах LUA из “HandicraftSDK\CMD-utilities\Shell\Integration(\RU)”, а так же после настройки ассоциаций FAR-а согласно “!Integration of $SqlTrans with FAR Manager.txt” (или же “RU\!Интеграция $SqlTrans с FAR Manager.txt”) — всё становится довольно-таки удобным для программирования с применением SQL-файл.

Обратите внимание на папку(и): “HandicraftSDK\CMD-utilities\Shell\Integration(\RU)”.

II.2. Трансляция множеств (файлы SQL)

Помимо простой трансляции отдельного файла, имеется возможность обработать группу / подгруппу SQL. Для запуска подобной трансляции применяются, как правило, простые стартеры CMD. В одну трансляцию могут попадать не только файлы шаблона “*.sql”, но так же (при соответствующем запуске $SqlCmd) и сразу несколько подпапок, а так же и некоторый специальный SQL-файл. Порядок обработки файлов перестраивается посредством простейших файлов коррекции $sql_order.list. Сложные же (составные) трансляции описываются соответствующими CMD-сценариями. Подобные сценарии играют в SQL-файл значительную роль (удаление файла, запрос подтверждения, формирование текстового отчёта, и т. п.).

В загрузке, соответствующей Handicraft-SDK, присутствуют три условных SQL-проекта (перечислены в SQL-project-list.txt), а в состав BookRegistry app. входит один сложный (из 2-х разнесённых частей) SQL-проект.

II.3. Слабый и сильный препроцессинг (осуществляется подпрограммой SqlCatPP)

При использовании Environment зачастую нормальным будет положиться на поведение базового средства SQLCMD. По умолчанию (при обращении к $SQLTRANS) SqlCatPP (EXE) применяет так называемый “слабый препроцессинг”, затрагивающий одну лишь директиву :SetVar. Он попросту добавляет перед ней одну строчку-комментарий: --:SetVar … (чтобы иметь неиспорченную диагностику относительно номера строки ошибки). Однако, когда Вы не взаимодействуете с БД напрямую, а отдаёте свои скрипты дилеру (посреднику), то возникает потребность в тщательной подготовке такого скрипта, с учётом Environment SQL-проекта. (Навряд ли удастся на стороне дилера использовать какие-либо окружения.) В данном случае необходим так называемый “сильный препроцессинг”, который реализуется в SqlCatPP в тестовом виде, затрагивает директивы :SetVar, :r, а так же ссылки на переменные среды: $(<ИмяПеременной>). Результат подобной обработки доступен для примера в подкаталогах $OUTPUT и $GENERATED проектов SQLAUX и “Extralight-ORM test legacy sample (En+Ru)\MyFlat app. (MVC_Razor+TS+ADO+TSQL)\SQL (DB-modelling)”. В состав sqlaux_library.sql (из $OUTPUT), например, входят (как минимум) 173 исходных SQL-скрипта (фрагменты с разделителем GO), присутствующие так же и в $GENERATED (с порядковым префиксом имени файла: XNNN.<BaseFileName>.sql). Сильный препроцессинг включается CMD-инструкцией set SqlCatPP.ProcessDirectives=1, располагающейся, как правило, в корневом сеттинг-файле SQL-проекта $sql_settings.cmd.

Так же, утилита $SQLTRANS имеет возможность производить т. н. фиктивную трансляцию (set $sqltrans.TranslateToDatabase=0), выводить данные в текстовый файл результатов (для этого необходимо задать действительный 2-й параметр, например: $SqlTrans "%~n0.sql" "%~n0.txt"), а так же поддерживает передачу дополнительных параметров в базовый SQLCMD (например: set $sqltrans.AdditionalParams=-y0, set $sqltrans.ContinueOnBatchError=1). И не только это (см. страницы, картинки и загрузки).

II.4. Два основных направления в использовании SQL-файл

Технология SQL-файл применяется для достижения следующих 2-х основных целей:

1) Хозяйственная обработка базы данных MSSQL: добавление таблиц, наполнение их данными, правка структуры БД, прочие рутинные операции административного характера. Поскольку всё оформляется в виде файлов, то то или иное действие может быть повторно воспроизведено впоследствии (с соответствующей доработкой скриптов).

2) Программирование в базе данных MSSQL, а именно — написание подсистемы хранимых объектов кода SQL (процедуры, функции, триггеры, представления), которые в терминологии SQL-файл обозначаются как программатик-и (общий термин). Серверную SQL-часть приложения принято, зачастую, генерировать целиком — удалять все (или подгруппу) программатики (соответствующие, например, такому-то именному префиксу) и создавать их заново. (Данное действие можно производить на разных экземплярах сервера и БД, указываемых в корневом $sql_settings.cmd соответствующего SQL-проекта.)

III. Небольшая попытка создания экспериментальной псевдо-микро-ORM для доступа к своим SQL-запросам и ХП, бок-о-бок файлы (SQL/C#) и прочее

III.1. Техника Side-by-Side (SQL/C#)

В экспериментальных проектах “Client-Server.WEB (idea)” а так же “MyFlat app. (MVC_Razor+TS+ADO+TSQL)” была предпринята небольшая попытка непрямого соединения исполняемого SQL-сервером кода Transact-SQL с исполняемым веб-сервером ASP C#-кодом для .NET. В 1-м случае подобный CS-код, так же (с учётом соответствующих директив условной компиляции), работает в браузере (применяется WASM-Blazor), что привносит дополнительные усложнения. Каждый запрос к БД оформляется в виде 2-х рядом лежащих файлов с одним и тем же базовым именем: “<ИмяЗапроса>.sql” и “<ИмяЗапроса>.cs”. В данном случае под SQL-запросом понимается код хранимой процедуры T-SQL, который “попадает” на сервер в момент трансляции SQL-файла, каталога с файлами либо всего большого проекта (с применением $SqlTrans+SqlCatPP).

Соединение SBS-файлов условное (смешения кода нет). Данное исполнение стремится видеть (представлять) SQL-запросы в довольно унифицированной форме: с параметрами ХП, статусом возврата @Status uniqueidentifier = null out (параметр), сообщением ошибки @Message $(dt_Message_AUX) = null out, с возможными несколькими резалт-сет-ами. (В последующей неопубликованной версии аналогичного SDK данные параметры имеют, соответственно, имена @RStatus и @RMessage.)

Легковесный ORM к ХП и SQL-запросам (Handicraft-CODE): https://handicraft.remelias.ru/csweb/lightweight_orm.html

Попытки успешного смешивания разнородного кода известны. Например: “.razor” и “.cshtml” (смешение HTML+C#) — используются для генерации HTML-разметки посредством C#, с частичной проверкой правильности разметки. При компиляции же SQL-процедуры (например, из файла SQL) — так же проводится определённая проверка правильности SQL. Совмещение SQL+CS возможно было бы, в определённой степени, усовершенствовать. Например, в некоторых трудоёмких случаях — использовать объявление параметра (с типом) по месту его применения в теле запроса, “поручив” оформление заголовка(ов) запроса(ов) генератору-препроцессору SQL (добавив в него соответствующую функциональность). Так же, используя специальный вспомогательный формат двойственного (SQL-сервер/SQL-клиент) определения значений и типов, теоретически возможно было бы достичь определённого успеха. Однако, смешивание кода, работающего в совершенно разных средах и местах, навряд ли должно выглядеть просто.

В примере BookRegistry app. излишнюю сложность, однако, привносит использование JSON, а так же желание надёжно “защититься” (проверки-исключения) от Null-ов на стороне C# (после передачи данных через HTTP в упакованном виде, посредством JSON). В примере же “MyFlat app. (MVC_Razor+TS+ADO+TSQL)” применяется сочетание 2-х языков для наименований: английский (ASP веб-сервер) <=> русский (объекты в SQL-БД).

III.2. Зачем всё это нужно (или же почему не всё так складно в ORM)?

Данный пункт можно отнести к области фантастики. Он предполагает существование возможности вносить изменения/дополнения в некоторую реляционную СУБД, поддерживающую расширяемый диалект языка SQL.

В настоящее время, при доступности применения ORM для взаимодействия с БД, её (одну из ORM) естественно будут использовать очень многие. Несмотря даже на то, что подобное применение зачастую ведёт к определённому перевороту, когда, например, язык C# может быть поставлен выше базы данных, как принято на это смотреть в контексте применения EF Code First, и любое общение/взаимодействие с БД (даже не от имени разрабатываемого приложения) подчиняется уже C# и особенностям Entity Framework (при использовании Code First). А ежели подход с центральным Code First — это востребованное передовое, то всё, что не Code First — уже не годится (не то, что надо) и т. п. Есть и другие причины, так же говорящие в пользу применения своих SQL-запросов для общения с сервером SQL. (Крупные базы данных, кстати, способны пережить и несколько клиентских фреймворков и ORM.)

Что же касается использования хранимых процедур в БД для приложения, то существует обоснованное мнение, что это (1) не современно, (2) не кроссплатформенно, а так же (3) тяжело в поддержке. Поэтому — опять приходим к ORM, большой ORM. (И даже микро-ORM применять, как правило, обычно не рекомендуется.)

Непростая идея компилируемых запросов SQL:

Бок-о-бок файлы (приводятся выше), реализованные автором статьи в экспериментальном виде на базе классических хранимых процедур-запросов MSSQL, могли бы, так же (потенциально), при должной поддержке со стороны СУБД, быть исполнены, по части обработки SQL, в виде так называемых “Компилируемых запросов SQL” (Compiled SQL Queries с ограниченным управляемым временем жизни), поддерживаемых гипотетическим SQL-сервером (с функцией Compiled SQL Queries). Компилируемые SQL-запросы возможно было бы унифицировать по части заголовков с параметрами-значениями, параметрами-таблицами, резалт-сет-ами, кодом/статусом/сообщением возврата и т. п. (Т. е. — такие специальные кроссплатформенные по отношению к диалектам SQL заголовки для SQL-запросов.) Хранящийся в SQL-файле клиента SQL-сервера параметризованный код (параметры запроса + клиентская Environment) должен соответствующим образом подготавливаться (“на лету” при первом запуске запроса, или, возможно, на старте приложения):

  • сначала (на стороне клиента SQL) — применение аналога Environment SQL-проекта;

  • далее (на стороне клиента) — препроцессинг SQL (раскрытие аналогов переменных среды);

  • затем — подготовка на SQL-сервере, с проверкой ошибок (компиляция аналога временной ХП с параметрами, со специальным уникальным наименованием временно сохраняемого запроса).

Исправление же кода в файле с SQL-запросом приложения на работающей программе (желательно это делать, конечно, не в части заголовка) — должно восприниматься как необходимость повторной компиляции (когда потребуется) временного запроса: уничтожение/создание временного запроса+имени на сервере SQL. По-видимому, стоит предусмотреть несколько разрядов (степени долгожительства), отвечающих за продолжительность существования таких запросов на сервере, — от эфемерных до практически постоянно сохраняемых запросов.

Таким вот примерно образом автор статьи представляет себе общение с базой данных SQL на языке SQL, со стороны программы (например веб-сервера), использующей какой-либо компилируемый либо скриптовый язык. Для работы такого приложения потребуется технология, подобная SQL-файл (обозначим расширение как SQL-file-app.). Компилируемые запросы приложения (SQL-файлы) могли бы заранее (на этапе разработки) проверяться специальными командами трансляции (отсылаться на сервер) на предмет ошибок предварительной подготовки (компиляция запроса на стороне SQL). Более того: базирующиеся на SQL-файлах компилируемые запросы должны быть доступны из папок SQL-проекта для исполнения их отдельно от, собственно, приложения, — как из подготовившего запрос файла сценариев, так и из специального проверочного или хозяйственного SQL-скрипта, работающего в контексте того же (подготовившего запрос) SQL-подключения.

Кроме того, обычная (подобная существующей в исполнении автора статьи, для MSSQL) не расширенная функциональность технологии SQL-файл, так же могла бы оказаться весьма полезной для работы вокруг подобного приложения.

IV. Завершение (резюме)

Как было обозначено в начале пункта III.2, то, о чём (в п. III.2) фантазируется автором статьи, весьма удалено от нашей реальности. И всё же (насчёт реальности): несмотря на могущество отдельных диалектов SQL, длительную историю знаменитых СУБД, трудно, в контексте понимания того, как обычно оформляются/выглядят запросы к базе данных (SQL-вкрапления в другую программу, либо посредством драйвера большой и умной ORM, либо же с применением отдельного SQL-файла или объекта с кодом, открываемом в консоли-редакторе БД), — трудно называть SQL первосортным языком программирования, который мы можем полноценно поддерживать (с тем же комфортом, что и классические языки ООП), когда применяем SQL для взаимодействия с БД из кода приложения или из отдельного скрипта.

Комментарии (6)


  1. Tzimie
    25.06.2022 18:51
    +6

    Я 25 лет работаю с MS SQL, но ни понял ничего. Что, зачем? Автор существует в каком то своем контексте


  1. vagon333
    25.06.2022 19:00
    +4

    Вероятно, вы глубоко в своей задаче и позабыли, что пользователь не курсе проблемы.
    Какую проблему вы решаете в этой статье?


  1. qwertEHOK
    26.06.2022 11:43

    ну прочтите внимательно же)

    автор реализовал приложение на C# для обработки файлов .sql на стороне клиента плюс какое то расширение функционала самого sql

    но конечно с примерами беда


    1. SergeiKitaev Автор
      27.06.2022 19:05
      -2

      Добрый день!

      *** ПО ПОВОДУ ПРИМЕРОВ. ***

      Стоит заметить, что любой файл .SQL из загрузок (а так же: .CMD, .LIST, .TXT) является, в каком-то смысле, небольшим примером.

      Примеры, как таковые, располагаются в следующих местах:

      = I.=
      В ЗАГРУЗКАХ: например “Handicraft_Toolkit_20210910.7z” (комплексная):
      Там имеется файл-описатель: “HandicraftSDK\SQL-project-list.txt” (основные примеры):
      [[
      List of SQL-projects in Handicraft-SDK (SQL-file technology)

      Project folders (with root "$sql_settings.cmd"):

      1) HandicraftSDK\SQL\SQLAUX\Source;

      2) HandicraftSDK\SQL\Programming samples (SQL-file)\**;

      3) HandicraftSDK\SQL\Extralight-ORM test legacy sample (En+Ru)\MyFlat app. (MVC_Razor+TS+ADO+TSQL)\SQL (DB-modelling).

      — — —
      ]]
      А ТАК ЖЕ, В РАСШИРЕНИИ ПРИМЕРОВ (эксперимент Client-Server.WEB):
      BookRegistry\SQL (DB-modelling)\**” (SQL, CMD) и “BookRegistry\SHARED\$ClientServer\!DB-queries (application SP)\**” (CS+SQL).
      (см. так же: https://handicraft.remelias.ru/csweb/client_server_web.html)

      = II.=
      В БАЗЕ ДАННЫХ [TEST], ДОСТУПНОЙ ДЛЯ “ПОДНЯТИЯ” ЛИБО ПОДКЛЮЧЕНИЯ:
      Файл “TEST (DB)!DB-info.txt”:
      [[
      Test database for BookRegistry and MyFlat sample applications

      === Content (files): ===

      1) TEST 2021-08-25.BAK — MSSQL-backup file;

      2) TEST 2021-08-25\TEST.mdf — main data-file;

      3) TEST 2021-08-25\TEST_log.ldf — database log-file.

      Microsoft SQL Server 2017 (140)+
      SQL-Server database:
      – compatibility level: Microsoft SQL Server 2017 (140);
      – collation: Cyrillic_General_CI_AS;
      – name: TEST (DB logical names: TEST, TEST_log).
      ]]
      Там же, в папке “TEST (DB)”: “TEST 2021-08-25.BAK”, “db_restore.sql”, “db_attach.sql” и др.
      В БД, однако, можно увидеть (посмотреть SQL) лишь оттранслированные объекты, с развёрнутыми исходными переменными окружения $(<Имя переменной>).

      = III.=
      — В МНОГОЧИСЛЕННЫХ КАРТИНКАХ (СКРИНШОТ-Ы), ЧУДЕСНЫМ ОБРАЗОМ ЗАМЕНЯЮЩИХ МНОЖЕСТВО СЛОВ:

      https://handicraft.remelias.ru/sdk/sql_file.html#screenshots
      https://handicraft.remelias.ru/sdk/sql/screenshots_1.html
      https://handicraft.remelias.ru/sdk/sql/screenshots_2.html
      https://handicraft.remelias.ru/sdk/sql/screenshots_3.html
      (см. также: https://handicraft.remelias.ru/sdk/sql_file.html,
      https://handicraft.remelias.ru/sdk/sql_tools.html и
      https://blog-hc.remelias.ru/)

      https://handicraft.remelias.ru/csweb/screenshots/dev_screenshots.html
      https://handicraft.remelias.ru/csweb/screenshots/dev_screenshots_sql.html
      (см. так же: https://handicraft.remelias.ru/csweb/client_server_web.html;
      https://blog-hc.remelias.ru/client-server-wasm-application-in-cs-typescript-and-t-sql/,
      https://www.c-sharpcorner.com/article/client-server-wasm-application-in-c-sharp-typescript-and-transact-sql/)

      *** НАСЧЁТ РЕАЛИЗОВАННЫХ ИДЕЙ: ***

      = I.=
      Основная идея SQL-файл очень простая: запускать (исполнять скриптовый код на SQL-сервере) сконфигурированные SQL-файлы, снабжённые настраиваемым окружением различной сложности. Т.е., выбрал с помощью пульта файл-команду (SQL либо CMD), нажал кнопку запуска — увидел консоль исполнения с выводом и/или, возможно, просмотрел отчёт-вывод в файле .TXT. Файлы CMD, кстати, нормально запускаются и из Windows Explorer, по двойному щелчку мыши. (Т.е. не обязательно везде задействовать Far Manager.) Дерево исходников — это всегда такой маленький (или средний по размеру) автономный SQL-проект, с существенной составляющей от слова конфигурация (или сеттинг-и). При таком подходе (SQL в файлах) бывает, как правило, критически важен порядок обработки последовательности этих файлов. Так же, иметь возможность исполнять отдельный файл, обрабатывать подгруппу, большую группу, производить составные трансляции (с задействованием сценария), — становится просто необходимо.

      = II.=
      Ещё одна идея — снабдить основной блок перехватчиком исключений, посредством ключевых макро-слов: $(BEGIN_AUX) и $(END_AUX), что позволяет уйти (не использовать) от того безумного Control Flow (при отсутствии перехвата исключений, с проверкой @@ERROR везде-везде), доставшемуся T-SQL по наследству от самых старинных версий MSSQL.

      = III.=
      В некоторых случаях, однако, нет возможности применять какие-либо специальные утилиты. Вы передаёте т.н. дилеру SQL-скрипт(ы), предназначенный(ые) для разворота или обновления SQL-кода удалённой подсистемы. (Т.е. у Вас нет доступа к БД.) Дилеру доступны только стандартные инструменты, как правило SQL-Server Management Studio (и всё). Для подобного случая возможно (аккуратно, с проверками у себя на месте) подготовить для него развёрнутый(ые) скрипт(ы) с учётом Вашей конфигурации, — используя функцию т.н. сильного препроцессинг-а. Например, библиотека SQLAUX может быть отправлена дилеру в виде одного “развёрнутого” (все объекты, с учётом Environment SQLAUX) файла: “HandicraftSDK\SQL\SQLAUX\Source$OUTPUT\sqlaux_library.sql” (тут есть и удаление и создание и, даже, кое-где, наполнение таблиц).
      Сильный препроцессинг, вообще-то, небезопасен, поскольку проблематично запрограммировать обработку директивы :SetVar с учётом комментариев, строковых литералов и разделителя батч-ей GO с точно таким же поведением (во всех мелочах), как у SQLCMD.
      Обычный же, слабый препроцессинг необходим лишь для устранения эффекта сбоя диагностики номера строки, присутствующего у SQLCMD за счёт необдуманного “съедания” в отправленном на SQL-сервер скрипте строки с директивой :SetVar. Кстати, для :setvar (строчными буквами) или же :SETVAR (заглавными), препроцессинг вообще не должен задействоваться. (Для :SetVAR дублирование вида --:SetVAR … будет производиться всегда, без анализа того, комментарий ли это /*…*/, строковый литерал, или же обычный фрагмент SQL-кода.) Препроцессинг, собственно, является встроенной функцией SQLCMD, и не стоит сильно “отрываться” от этого замечательного инструмента, режим которого поддерживается (при включении настройки) так же и в IDE SSMS. В наименовании же утилиты SqlCatPP (EXE) слово Preprocessor (“PP”) идёт после слова Catenation (“Cat”). Основная его функция это, всё-таки — сцепление нескольких SQL-файлов (как правило имеющих разделитель GO) для передачи большого слитного скрипта утилите SQLCMD, которая, в свою очередь, обработав его стандартным образом, уже отправит окончательные пакеты-батч-и на SQL-сервер.

      = IV.=
      SQL-файл возможно задействовать как минимально, так и с интенсивным обращением к расширениям.
      Можно не подключать библиотеку SQLAUX, не ссылаться в пользовательском скрипте на раскрывающиеся её слова вида $(…_AUX).
      Возможно, напротив, использовать кое-что из коллекции оттранслированных (посредством, например, “HandicraftSDK\SQL\SQLAUX\Source\translate_programmatics.cmd”) в пользовательскую БД вспомогательных программатик-ов, таких как “AUX:DropProcedure”, “AUX:ToString.Int”, “AUX:IsInServerAdminRole” (см. “HandicraftSDK\SQL\SQLAUX\API (headers)\Programmatics.AUX.txt”; см. https://handicraft.remelias.ru/sdk/sql_file.html#sqlaux_programmatics).
      Из файла сеттинг-ов “$sql_settings.cmd” (папка “SQLAUX\Source”):
      [[
      : : : : :
      set $sql_server=(local)
      set $sql_database=TEST
      : : : : :
      ]]
      (Потребуется указать пользовательскую БД.)

      = V.=
      Помимо, собственно, SQL-файл, в статье присутствуют идеи, относящиеся к экспериментальным и теоретическим.
      — См. “Client-Server.WEB (idea)”: https://handicraft.remelias.ru/csweb/client_server_web.html;
      — Последняя перед заключением большая часть статьи, представленная номером III:
      III. Небольшая попытка создания экспериментальной псевдо-микро-ORM для доступа к своим SQL-запросам и ХП, бок-о-бок файлы (SQL/C#) и прочее:
      III.1. Техника Side-by-Side (SQL/C#);
      III.2. Зачем всё это нужно (или же почему не всё так складно в ORM)?

      *** ФОРМИРОВАНИЕ ТЕХНОЛОГИИ SQL-ФАЙЛ: ***

      Когда-то, имея дело с ранними версиями Microsoft SQL Server, автор статьи долго испытывал удивление по поводу того, насколько ненадёжно (“неудобно”) устроен язык Transact-SQL в плане обработки ошибок. Так же, работа с запросами, их редактирование непосредственно в БД посредством графической консоли (хранимые процедуры, функции, триггеры и т.п.), — всё это было и остаётся весьма далёким от совершенства. После многолетнего удивления возникла (постепенно сложилась) технология SQL-файл, позволявшая держать скрипты в директориях и файлах (и применять их непосредственно оттуда). Каждый скрипт в SQL-файл всегда должен располагаться в правильном месте, с соответствующими настройками окружения проекта / каталога. Такой, казалось бы, более трудоёмкий подход позволяет, однако, эффективно воссоздавать сохранённые подсистемы, вносить коррекции, применять скрипты (массово и по отдельности) к другим экземплярам БД. Поскольку проект в SQL-файл — автономный (не нуждается в SSMS), ему потребуются редактор(ы) и пульт для исполнения команд, коих предвидится немало. Посему, как самый совершенный из файловых командеров, был выбран Far Manager (в качестве основного пульта для SQL-файл). (Примечательно, что в Америке нет моды на командеры; каждый вендор ПО пытается либо предложить своё собственное исполнение для IDE, либо осуществить интеграцию в фирменную IDE.) Возможности Far Manager позволяют использовать его как универсальную IDE, в данном случае для автономного проекта, с применением так же и дополнительного расширенного GUI-редактора SQL (вызывается для .SQL из панели по <Shift+Enter>). В SQL-файл нет какого-то ярко выраженного особо-центрального элемента. Все компоненты в определённой степени важны и работают в комплексе, однако не все её средства обязательны для применения. (Использование технологии чем-то похоже на применение конструктора вокруг множества файловых SQL-скриптов, для обслуживания подсистемы внутри БД.) С помощью SQL-файл, в первоначальных её представлениях, в течение долгого времени поддерживались (в прошлом) базы данных для расчёта квартирной платы в городе Воронеж.

      Спасибо за внимание и Ваш отзыв!


  1. Mikluho
    26.06.2022 14:21
    +1

    Уважаемы автор! В этой статье, написанной в стиле прошлого столетия, вы забыли главное - рассказать о том, что заявлено в заголовке: "Технология SQL-файл".
    Есть отдельные кусочки описания, но понять, что же такое на самом деле, прочитав статью, невозможно. При этом вы много рассказываете про перечисляете используемые командеры, хелперы, эксперименты, собственные статьи...

    Но где сам "SQL-файл?
    Хоть бы один пример такого проектика? С описанием задачи, решаемых проблем...
    А то, всё, что есть, это фраза, где-то в цитате, "Идея состоит в том, чтобы поддерживать исходный код и/или вспомогательные скрипты в виде SQL-файлов в директориях, транслируя их в базу данных, по отдельности либо группами. "

    Если ваш "SQL-файл" - это хиленький препроцессор и cmd для выполнения скриптов БД, то не понятно, а что в нём интересного, кроме кучи устаревших подходов?
    Кодогенерация - так есть куча альтернатив (и они сильно мощнее простенького препроцессора). Апдейт базы - так есть миграции (и это не обязательно ORM). Редакторы кода - тем более. И всё это нормально дружит с git и devops, что сильно снижает трудозатраты и риск ошибки...

    Иначе говоря, скажите, какую проблему решает ваша технология, которую (проблему) не решают другие популярные современные решения.


    1. SergeiKitaev Автор
      27.06.2022 19:41

      Добрый вечер!

      *** О ТОМ, ЧТО ЗАЯВЛЕНО В ЗАГОЛОВКЕ: ***

      Заявлено и в заголовке статьи и в названии технологии, — ничего возмутительного; самые, казалось бы, естественные вещи присутствуют в SQL-файл.
      В своём ответе на предыдущий комментарий “ну прочтите внимательно же) … но конечно с примерами беда” от qwertEHOK 26.06.2022 в 11:43 автор приводит разъяснения: “ПО ПОВОДУ ПРИМЕРОВ”, “НАСЧЁТ РЕАЛИЗОВАННЫХ ИДЕЙ”, “ФОРМИРОВАНИЕ ТЕХНОЛОГИИ SQL-ФАЙЛ” (см. выше).
      Идея предельно проста: хранить исходный код в правильно организованной директории на клиенте; там же его редактировать, оттуда его и применять (транслировать скрипты в БД). Это очень просто на словах. В реальности же всё оказывается нетривиально: много команд (простая / составная трансляция); обработать отдельный файл / группу () / большую группу; определение собственных раскрывающихся слов / констант $(<Имя переменной>); организация порядка трансляции; расположение файлов в папках дерева. Автор не утверждает, что всё решается идеально. Эта небезупречная реализация, однако, действительно позволяет поддерживать подсистему внутри БД, опираясь на файлы, как исходное место для усиленного SQL (создание/удаление табличной структуры, хранение кода ХП, функций, представлений, триггеров). В базе данных на самом деле — не совсем-таки исходники, а фрагменты скриптов с учётом сеттинг-ов (с уже раскрытыми переменными пользовательского проекта / каталога / трансляции). Для нормальной коррекции такого скрипта необходимо править исходный SQL-файл и применять его. Т.е. стандартная графическая консоль для доступа в БД используется по минимуму (как правило не для правки того, что присутствует в файлах).

      Вот пример того, как раскрывается обёртка основного блока:

      ИСХОДНЫЙ СКРИПТ (SQL-ФАЙЛ):
      [[
      $(BEGIN_AUX)
      -- ТЕЛО ЗАПРОСА:
      : : : : :
      $(END_AUX)
      ]]

      СКРИПТ ДЛЯ ИСПОЛНЕНИЯ СЕРВЕРОМ SQL:
      [[
      begin set xact_abort off; set ansi_nulls,ansi_null_dflt_on,quoted_identifier,arithabort,nocount on; set implicit_transactions off; declare @initial_tran_count_aux int, @is_local_tran_open_aux bit; select @initial_tran_count_aux=@@trancount, @is_local_tran_open_aux=0; begin try
      -- ТЕЛО ЗАПРОСА:
      : : : : :
      if @is_local_tran_open_aux=1 raiserror ('Not closed local transaction was detected, previously opened by BEGIN_TRANSACTION_AUX macro.',11,1); end try begin catch if @is_local_tran_open_aux=1 and (@@trancount>@initial_tran_count_aux or xact_state()=-1) rollback transaction; set @is_local_tran_open_aux=0; throw; end catch; end
      ]]

      *** ГДЕ НАХОДИТСЯ САМ SQL-ФАЙЛ: ***

      SQL-файл располагается в директории-проекте (рядом с другими с SQL-файлами) у разработчика / администратора. Проект снабжается сеттинг-ами “@sql_settings.cmd”. Корневые сеттинг-и, часто ссылаются на настройки проекта “@<Имя проекта>.cmd” (в кодировке UTF-8). “@sql_settings.cmd” из подпапки проектного дерева обычно ссылается на “@sql_settings.cmd” более высокого (директория выше) уровня и иногда дополняет/модифицирует родительские сеттинг-и.

      *** “ХИЛЕНЬКИЙ ПРЕПРОЦЕССОР”: ***

      Как было сказано в ответе на предыдущий комментарий, функция слабого препроцессинг-а нужна, прежде всего, чтобы устранять сбой диагностики номера строки, присущий SQLCMD за счёт т.н. “съедания” директивы :SetVar стандартным препроцессинг-ом (в SQLCMD). Сильный же препроцессинг требуется лишь в особых случаях и содержит элемент риска (эта функция появилась в SQL-файл последней и ещё недостаточно опробована). Как говорится в соответствующем разъяснении, препроцессинг — не главное, в отличие от конкатенации группы исходников (снабжённых, как правило, разделителем GO). Смотрите ответ автора на предыдущий пользовательский комментарий.

      *** ПРОБЛЕМЫ, РЕШАЕМЫЕ SQL-ФАЙЛ: ***

      Смотрите ответ автора на предыдущий пользовательский комментарий: “НАСЧЁТ РЕАЛИЗОВАННЫХ ИДЕЙ” и др. В общих словах можно кратко обозначить две грустные особенности касательно взаимодействия разработчика с SQL:

      1)Ненадёжность (“неудобство”) языка Transact-SQL в плане обработки ошибок, — обременительный (в режиме по умолчанию) Control Flow, выражающийся в необходимости проверки @@ERROR везде-везде. Для решения этой проблемы была придумана обёртка основного блока запроса, в виде раскрывающихся слов: $(BEGIN_AUX) и $(END_AUX) (см. выше).

      2)Ограниченность и неполноценность взаимодействия с SQL-сервером через фирменную консоль. База данных не столь удачно подходит в качестве первичного хранилища скриптов. Даже если Вы их уже извлекли из БД и храните в системе управления версиями, что это означает? Как быть с клиентским окружением SQL-проекта; где оно тогда присутствует с доступностью для исправления, влияющего на множество скриптов? Где определяются трансляции файловых групп (для соответствующих SQL-объектов): множества файлов, их порядок обработки, команды применения?

      *** В ДУХЕ ПРОШЛОГО СТОЛЕТИЯ; КУЧА АЛЬТЕРНАТИВ И Т.П.: ***

      Не совсем понятно, к чему здесь сравнение с прошлым столетием. Если так уж не нравится применение в статье абстракций (трансляция SQL, поддержка скриптов на файловой базе, программатик-и, сеттинг-и проекта / каталога / трансляции, настройки окружения, и т.п.), то всем этим терминам соответствуют вполне реальные вещи. Да и сам SQL, кстати, появился ещё в прошлом столетии. Только в отличие от большинства языков программирования, где принято использовать непосредственно файлы, в языке SQL в силу, быть может, присущей СУБД её серверной локации, клиентская составляющая не получила достойного развития. И вообще, всё, что придумывается, например электронная почта (в том виде, как мы её знаем), обретёт весьма отличное устройство, исполнение, терминологию и понятия, будь оно создано, к примеру, на другом континенте и / или же другими людьми.

      Насчёт альтернатив. В мире есть огромное количество всякого полезного добра. Однако, несправедливо отрицать результаты, полученные автором в ходе выработки и практического использования технологии SQL-файл на основании лишь того, что полезное добро повсюду успешно применяется. Существуют продукты, предназначенные для облегчения разработки в SQL, на которые SQL-файл чем-то (быть может) похожа по своему назначению. Однако, автору не известно конкретно ни одной штуковины, которая бы совпадала или существенно превосходила SQL-файл в плане полноценного программирования в SQL, ориентированного первично (т.е. изначально — скрипты) на файловую базу для размещения и правки исходников. И это, в результате (у автора), т.н. “кустарная” (handicraft) технология SQL-файл (в её текущем исполнении), — конструктор SQL-проектов, автономный, настраиваемый / расширяемый, с поддержкой простых командных сценариев, со средней степенью интеграции с редакторами и командными пультами.

      Всего доброго!