Технология SQL-файл — это не одни только сценарии, подобные CMD/PS/и т. п. Она скорее от слова “SQL-проект” (или конструктор SQL-проектов) — автономный, однако и доступный для интеграции (FAR, GUI-редактор простого текста, редактор SSMS). SQL-файл предлагает некоторую унификацию для взаимодействия с базовой утилитой MS SQLCMD: исходный(ые) файл(ы) SQL => $SQLTRANS => SQLCMD. Автор осмысленно не стал “отрываться” от SQLCMD (например, используя ADO.NET + C#), поскольку SQLCMD предоставляет уйму известных в документации параметров поведения (и не только поэтому).
I. По поводу препроцессинг-а, осуществляемого подпрограммой SqlCatPP
Исходные скрипты могут быть непростыми для разбора: комментарии, участки строкового литерала и т. п. Скрипты же с динамическими подзапросами (формирование строки подзапроса EXEC) могут оказаться коварными для специального (не от MS) обработчика T-SQL. В SqlCatPP по умолчанию включен т. н. “слабый препроцессинг” (см. ранее п. II.3 основной статьи). Сильный же препроцессинг (реализован в режиме тестирования), если это особо не требуется, включать не рекомендуется! А именно: не следует без необходимости использовать сеттинг “set SqlCatPP.ProcessDirectives=1”; желательно поставить в начале строки префикс комментария “rem …” (рекомендуется), либо установить параметр-опцию в значение 0. (В т. ч. — и в проектах SQLAUX и “MyFlat app. (MVC_Razor+TS+ADO+TSQL)”, где это в целях демонстрации включено.) Данная опция НЕ проверялась на “понимание” сложных скриптов!
Так же, доступно специальное отключение и для слабого режима препроцессинг-а (явно: “set SqlCatPP.InsertSetVarComments=0” и “set SqlCatPP.UnfoldEnvironmentVars=0”), для SqlCatPP. Препроцесинг-и НЕ тестировались на сложных скриптах! Однако, в слабом режиме — намного меньшая вероятность неудачи (ошибки) или иной досадной неприятности с подобной предварительной обработкой SQL. На обычной же сложности примерах-скриптах (таких как в Handicraft-SDK и не только) слабый препроцессинг SQL работает успешно.
SqlCatPP это, во-первых, конкатенатор исходных SQL-скриптов, а также (в зависимости от настроек-опций) и препроцессор. SQL-файл (в текущем исполнении) прежде всего полагается на SQLCMD, в том числе и касательно батч-ей T-SQL с применением разделителя GO. Подпрограмма SqlCatPP НЕ обрабатывает разделитель GO. Конкатенация же (сцепление) исходных скриптов осуществляется с учётом корректирующего файла “$sql_order.list” (“;SQL-TRANSLATION PRIMARY ORDER:”, из каталога файла SQL).
II. Взаимодействие с SQLCMD
Подобную команду можно видеть при т. н. запуске “list_programmatics.sql”:
[[
>> SqlCmd -S”(local)” -d”TEST” -i”C:\Users\serg\AppData\Local\Temp\$SQLTRANS\20210907_122616_89.sql” -o”C:\Users\serg\AppData\Local\Temp\$SQLTRANS\20210907_122616_89.txt” -b -w65535 -u
* Executing SQL …
=== LIST OF PROGRAMMATICS (SQLAUX LIBRARY): ===
Stored procedures
—————————————————————————————————-
AUX:DropFunction
AUX:DropFunctions
AUX:DropProcedure
AUX:DropProcedures
: : : : :
]]
По умолчанию SQLCMD получает от $SQLTRANS, так же (помимо параметров и др. ключей), ключ “-b (terminate batch job if there is an error)”. Однако, если установить “set $sqltrans.ContinueOnBatchError=1”, то ключ “-b” передаваться не будет. Можно, так же, передавать в SQLCMD и другие параметры: “set $sqltrans.AdditionalParams=…”. (Включение режима фиктивной трансляции: “set $sqltrans.TranslateToDatabase=0”. И т. п.)
Т. о. $SQLTRANS и SqlCatPP не пытаются заменить всё то, что умеет (на стороне клиента SQL-Server) многофункциональная утилита SQLCMD от MS.
III. Если отказаться от зависимости SQLCMD (а так же от использования процессора CMD)
Собираясь отказываться от задействования в трансляциях утилиты SQLCMD, разумным будет так же уйти от использования в SQL-файл сценариев CMD. Один из существенных недостатков установки свойств в CMD является, помимо затруднённого включения кодировки UTF-8 (без BOM-префикса), выражение переменной через переменную (в контексте формирования Environment). А именно: когда мы где-то в командном файле ссылаемся на несуществующее свойство (переменную), то это, с точки зрения CMD, не является ошибкой и воспринимается как пустой результат (фрагмент нулевой длины). Если, например, при обработке строки “set dt_Name_AUX=nvarchar(!num_NameCapacity_AUX!)” не было бы установлено заранее свойство “num_NameCapacity_AUX”, то “dt_Name_AUX” получило бы (молча) значение “nvarchar()” (вместо “nvarchar(100)”). SQL такой странный тип данных естественно не пропустит. Однако, не любая подобная ошибочная ситуация может столь успешно разрешаться (явной ошибкой на ранней стадии) на этапе восприятия сервером запроса SQL.
Несмотря на различные трудности, связанные со сценариями CMD, а также принимая во внимание многочисленные плюсы, которые предоставляет данный “legacy” процессор команд в контексте применения SQL-файл, трудно предложить полноценную достойную альтернативу для CMD. Отказываясь от SQLCMD+CMD, возможно, неплохо было бы разработать специальный формат сценария (свойства, типовые действия, условия и т. п.), допускающий так же выход на команды системы. Возможно, какой-нибудь из известных скриптовых кроссплатформенных языков мог бы, наверное, с должным успехом быть использован для подобных сценариев. Данная же реализация SQL-файл для MSSQL осмысленно придерживается SQLCMD, CMD, (опционально PS), сохраняя совместимость (ожидаемое поведение предварительной обработки SQL), а так же не стараясь отрываться от ряда полезных моментов (вещей) из прошлого. Это “кустарная” (handicraft) технология SQL-файл (в текущем её исполнении).
Автор блог-а
Китаев Сергей Юрьевич
Автор ресурса Handicraft-CODE
https://handicraft.remelias.ru/