Организация хранилища файлов внутри базы данных 1C+MS-SQL   

Довольно часто в различных вариантах учетных задач возникает проблема размещения различной информации (файлов) с привязкой их к базе данных. Например, построение на базе системы учета документооборота с хранением файлов в формате Word, Excel. Если организовывать такое хранилище в виде каталогов файлов, то очень велика вероятность нарушения работы системы в результате ряда факторов, вызванных, как правило, неумелыми, либо наоборот, «слишком умелыми» действиями пользователя. Другими словами система хранения файлов в каталоге базы , ввиду своей общедоступности является существенной прорехой в безопасности. Файлы легко переименовать, перезаписать, испортить или удалить.

Таким образом, мы постепенно подходим к мысли хранения файлов непосредственно в базе данных MS SQL. Остается вопрос, каким образом всё это можно организовать? В своей статье, я постараюсь дать как можно более подробный ответ на этот вопрос. Все исследования будут происходить на платформе MS SQL 2000, далее просто SQL.

Итак, первый вопрос на повестке дня – создание таблицы для хранения файлов. Как известно, SQL позволяет создавать таблицы, содержащие поля с типом IMAGE (в переводе на русский «образ»). В поле такого типа мы и будем хранить свой файл. Для обеспечения уникальности данных и возможности в дальнейшем получения доступа к файлу нам необходимо создать колонку с типом int, которая у нас будет иметь свойство «Identity». Это свойство обеспечит нам автоматическую нумерацию строк таблицы средствами SQL. Первоначальный номер у нас будет выставлен в «1», приращение номера будет тоже идти по «1».

Второй вопрос на повестке дня, – в какой базе создавать таблицу? Требуется ли для ее хранения отдельная база данных, или можно воспользоваться уже существующей базой данной . Как показали опыты, при операциях, затрагивающих базу данных, таких как выгрузка, загрузка, реструктуризация, работает только со «своими» таблицами не затрагивая те, которые отсутствуют в ее файле DDS. Это дает нам возможность поместить нашу таблицу непосредственно в базе данных . При этом, однако, следует иметь в виду, что раз не трогает «не свои» таблицы, то при выгрузке данных наша таблица выгружаться не будет. Поэтому, для обеспечения резервного копирования или переноса данных придется использовать средства SQL. С другой стороны, если мы помещаем нашу таблицу в отдельную базу данных, то получаем более гибкие возможности работы, в частности легче можно будет наладить репликацию данной таблицы, что немаловажно. В моем примере таблица будет расположена непосредственно в базе данных .

Теперь нам остается создать необходимый скрипт. Сразу определимся, что работать с хранимыми в базе данных файлами мы будем с использованием технологии ADO. Отсюда вытекает необходимость работы в нормальном рабочем режиме только в разделенном режиме работы -Предприятия, так как в монопольном соединение ADO не сможет получить доступ к базе данных.

Сделаем так, чтобы процедура проверки наличия необходимой таблицы в базе данных запускалась в из процедуры ПриНачалеРаботыСистемы() когда режим работы пользователя разделенный. Текст процедуры можно посмотреть здесь.

Теперь у нас есть в базе необходимая таблица. Следующая задача - научиться записывать в нее необходимые данные. Для этого мы воспользуемся такой возможностью SQL-сервера, как «BULK» операции. Это операции манипулирования большими объемами данных, точнее сказать это операции обмена данными между SQL-сервером и файлом определенной структуры, который может содержать как одну строку данных для SQL-сервера, так и большое их количество. Определение структуры данных, содержащихся в файле, происходит с помощью специального файла-формы.

Итак, мы определлись, что будем записывать файл в базу данных с помощью операции «BULK INSERT». В процедуре записи файла в базу данных, мы должны выполнить следующие действия:

  • получить последний номер строки и сохранить его в переменной;
  • создать и заполнить содержимым файл формы;
  • выполнить архивацию исходного файла для уменьшения его объема на сервере (не обязательно - у меня делается ввиду большого объема данных);
  • создать файл исходных данных;
  • выполнить запрос на размещение на сервере;
  • получить последний номер строки и сравнить его с сохраненным ранее значением;
  • если номер увеличился на «1» - значит операция прошла успешно, иначе - была ошибка.

Важное примечание: так как результирующий запрос будет выполнять сервер, необходимо, чтобы файлы, используемые сервером были доступны для него. Соответственно, при формировании путей к файлам мы должны «смотреть на них» со стороны сервера. То есть, получив запрос на размещение файла «C:myfile.doc» сервер будет искать его именно на своем диске, а не на компьютере-клиенте. Лучше всего сохранять файлы в сетевых папках доступных серверу и сразу указывать сетевые пути.

Текст процедуры глобального модуля осуществляющей размещение файла в таблице базы данных SQL можно посмотреть здесь.

Следующий вопрос, который нам предстоит решить - каким образом можно извлечь файл из базы данных. Тут дело обстоит сложнее. Придется воспользоваться утилитой BCP, входящей в состав поставки MS SQL сервера. Эта утилита служит для пакетного обмена данными с SQL сервером. В принципе, мы могли бы воспользоваться этой утилитой и для загрузки файла на сервер, но, думается, что, чем меньше будет мелькать дополнительных окошек, тем лучше. Принцип использования утилиты такой же как у команды «BULK INSERT», с тем различием, что нам нужно получить данные с сервера, а не загрузить на него.

Таки образом список действий, который нам надо выполнить становится намного короче:

  • создать файл формы;
  • выполнить утилиту BCP с параметрами;
  • разархивировать полученный файл (если использовалось архивирование).

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

 


 

Перепечатка, воспроизведение в любой форме, распространение, в том числе в переводе, любых материалов с сайта www.softpoint.ru возможны только с письменного разрешения компании "СофтПоинт". Это правило действует для всех без исключения случаев, кроме тех, когда в материале прямо указано разрешение на копирование (основание: Закон Российской Федерации "Об авторском праве и смежных правах").