Расширяем возможности MS SQL Server с помощью хранимых процедур CLR



Не хватает какого-то функционала на скуле для обработки данных? Тогда он (новый функционал) идет к вам.

Ни для кого (?) не секрет, что начиная с версии 2005 в MS SQL Server можно создавать хранимые процедуры не только на T-SQL, но и на управляемом коде. А в последних редакциях даже и на Python.

В каких сценариях это может пригодиться? Да в любых, где вам уже не хватает стандартных возможностей по манипулированию с данными, например, если вы захотите прямо в скуле "на лету" получать данные, хранящиеся в поле, соответствующее 1С-ному ХранилищуЗначений 😉

Здесь не будет чего-то нереально сложного, среднестатистический 1с-ник сможет сам разобраться в данной теме, покопавшись в интернетах.

Не буду утомлять демагогией, приступим.

Поставим некоторую простую задачу, например, вычисление контрольной суммы, пусть будет MD5, от значения двоичных данных. (В скуле "из коробки" уже присутствует такая возможность, зато будет с чем сравнить свою поделку).

Делать сборку на управляемом коде будем на современном и мощном языке C#.

Сначала нам надо создать ключ подписи, он нам в дальнейшем пригодится. Делается это с помощью консольной утилиты "sn", входящей в состав SDK Windows:

sn.exe -k MD5CS.snk

Далее в любом текстовом редакторе необходимо создать файл, назовем его "MD5CS.cs". В нем будем писать движок нашего алгоритма:

Создадим класс, в нем статический void метод, перед методом разместим атрибут [Microsoft.SqlServer.Server.SqlProcedure], добавим требуемые пространства имен: System.Data.SqlTypes, System.Data.SqlClient, Microsoft.SqlServer.Server. Метод будет принимать и возвращать данные типа SqlBinary, но возвращать уже по ссылке. Внутри метода реализуем алгоритм вычисления MD5 хэша:

using (MD5 md5Hash = MD5.Create())
{
byte[] data = md5Hash.ComputeHash((byte[])inputData);
value = (SqlBinary)data;
}

Не забываем добавить пространство имен System.Security.Cryptography.

Сохраняем файл и компилируем его с помощью стандартного компилятора CSC от MS, добавив ранее сгенерированную подпись:

csc.exe /t:library /keyfile:MD5CS.snk /out:MD5CS.dll MD5CS.cs

На выходе получаем управляемую самоподписанную сборку MD5CS.dll, её то и будем подгружать в скуль.

Остальную работу будем делать в Management Studio.

До версии MS SQL Server 2014 (если не ошибаюсь) для разрешения использования CLR достаточно было выполнить

EXEC sp_configure 'clr enabled' , '1';
RECONFIGURE;

В MS SQL Server 2024 уже гораздо сложнее. Оставлю здесь ссылку: deploying-sql-clr-assembly-using-asymmetric-key

После включения разрешений создадим на скуле объект сборки в разделе "Программирование":

CREATE ASSEMBLY MD5CS FROM '<PATH_TO_ASSEMBLY>MD5CS.dll'
WITH PERMISSION_SET=EXTERNAL_ACCESS
GO

Затем создадим нашу хранимку:

CREATE PROCEDURE MD5CSSUM (@binData varbinary(MAX), @md5sum varbinary(MAX) OUTPUT)
AS EXTERNAL NAME MD5CS.StoredProcedures.MD5CS;

Готово. Осталось проверить работоспособность, ну и для чистоты проделанной работы сравнить с оригиналом:

Вот такая магия )

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

На всякий случай предоставляю все исходники.

9 Comments

  1. AlX0id
    то, что раньше вычислялось на клиенте.

    Ну так что мешало взять и выполнить тот же код на сервере 1С?

    Вот ежели б можно было бы в итоге сделать

    «Выбрать МД5(ДокументСсылка) Из блбалаблатаблицаздесь»..

    Вот это было бы круто )

    Reply
  2. SerVer1C

    (1) А вдруг у вас сервера 1С нет? А вот, например, другой кейс: представьте — сервер 1с есть, вы храните паспортные данные, запакованные в хранилище значений, а вам надо, допустим, перенести в другую информационную систему, не связанную с 1с, некоторые данные по абонентам, прописанным в определенном районе (улице, округе и т.п.). Вам просто надо написать свою хранимку, которая распаковывает ХранилищеЗначений, регуляркой находит нужные адреса, вы в SQL выбираете нужные данные по условию MEGA_SUBSTRING() = «ЧТО_ТО_ТАМ» и переносите, куда вам надо. А по поводу «Выбрать МД5()» — это вам в фирму 1C надо заявлять о ваших «хотелках».

    Reply
  3. AlX0id
    А вот, например, другой кейс: представьте — сервер 1с есть, вы храните паспортные данные, запакованные в хранилище значений, а вам надо, допустим, перенести в другую информационную систему, не связанную с 1с, некоторые данные по абонентам, прописанным в определенном районе (улице, округе и т.п.). Вам просто надо написать свою хранимку, которая распаковывает ХранилищеЗначений, регуляркой находит нужные адреса, вы в SQL выбираете нужные данные по условию MEGA_SUBSTRING() = «ЧТО_ТО_ТАМ» и переносите, куда вам надо.

    Не вижу ни одного довода делать это не обработкой из 1С ) Все равно эффективного поиска по регулярке не выйдет в таких условиях.

    Более того — «просто надо написать свою хранимку, которая распаковывает ХранилищеЗначений» — звучит как минимум трудозатратно.

    Reply
  4. SerVer1C

    (3) Еще раз вам повторю: системы 1С у вас может не быть вообще! А про обработку в 1С *цать миллионов записей я вообще промолчу…

    Reply
  5. AlX0id

    (4)

    системы 1С у вас может не быть вообще!

    Хм. Ну разве что в таком варианте.

    Reply
  6. Darklight

    О, кстати, хорошая тема для применения нового 1С-подобного языка Перфолента — он как раз на платформе .NET а синтаксис косит в сторону 1С совместимости. Так можно писать внешнии функции для скуля почти «на языке 1С». Жаль только, что на этом преимущества заканчиваются — ни встроить их вызов в БД базы 1С (не нарушая лицензионного соглашения 1С), ни вызвать их напрямую из запроса 1С — возможности, увы, нет! От этого потенциал применимости резко снижается. Но, конечно, это остановит далеко не всех — кому «очень приспичит» — те сделают так, как тут написано — но 99% будут по старинке — обрабатывать всё на сервере, чтобы лицензионную политику не нарушать и не выходить за рамки ущербной платфрормы 1С Предприятие 8

    Ну и с базами 1С не все работают из самой 1С — а зачастую просто обрабатывают БД, для корой работа 1С платфорым уже не важна и не возможна — там да, всё это будет очень полезно! Но, обычно, там программисты и так уже знают как это всё устроить! Там другой уровень знаний специалистов, не как у простых 1С-ников 😉

    Reply
  7. GreenDragon

    (2) Если нет сервера 1С, то и базы ms sql нет. Или вы про кейс, когда ms sql база используется как хранилище внешних данных? При таком кейсе разумнее postgres или MySQL использовать. А тут прям какая-то, пардон, высосанная из пальца ситуация…

    Reply
  8. GreenDragon

    (4) Так у вас статья не для 1С-ников? Или она для 1С-ников, но которые с 1С не работают? В тексте публикации

    Здесь не будет чего-то нереально сложного, среднестатистический 1с-ник сможет сам разобраться в данной теме, покопавшись в интернетах.

    а в комментариях

    Еще раз вам повторю: системы 1С у вас может не быть вообще!
    Reply
  9. SerVer1C

    (7) Вам виднее…

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *