gifts2017

Хранение рисунков в отдельной базе MSSQL с помощью ADODB и Base64Строка

Опубликовал Ivon (Ivon) в раздел Программирование - Практика программирования

Обработка показывает, каким образом можно хранить рисунки (и не только) в базе MSSQL, а не в базе 1С. Полезно будет тем, у кого такая информация занимает в базе места больше, чем собственно данные.

Руководство решило хранить в базе сканированные копии всех договоров и сопутствующих документов. Все бы ничего, подвязали сканер к 1С, только за год база выросла до 100 гиг. С такой базой ни выгрузку нормально не сделаешь ни базу не поднимешь.

Надо было что-то придумать. Просто хранение файлов на файловом серваке нас не устраивало. Создавать для файлов отдельную базу 1С посчитали нецелесообразным. Решено было хранить данные в отдельной базу MSSQL. Только вот как это делать, никто не знал. На проекте видел несколько обработок, но они только читали данные из MSSQL, а нам нужно в базу писать, да еще и рисунки. Начался поиск решений. В итоге получилось то, что оформлено в данную обработку.

Для работы обработки нужен MSSQL сервер, .Net Framework 1.1 (он содержит ADODB.dll) на клиенте. На сервере создаем базу данных (в моем случае SomeDB) в которой создаем таблицу (в моем случае Pict), в которой создаем 2 колонки для ID рисунка и самого рисунка типа nvarchar(MAX). В обработке заполняем поля выше кнопки "Подключиться к SQL", нажимаем кнопку, в случае успешного подключения вводим имя таблицы, имена столбцов и ИД рисунка (произвольная строка). Выбираем рисунок, видим его внизу слева. Кнопка "Положить в базу" записывает рисунок в БД, кнопка "Выбрать из базы" получит рисунок с введенным ИД из БД и отобразит его в правой части формы. Открываем обработку в конфигураторе, смотрим как все реализовано, ставим плюс мне за труды.

Плюс данного решения - нет необходимости сохранять данные в промежуточный файл для просмотра в 1С.

Минус данного решения - примерный размер базы = размер данных * 3.

Скачать файлы

Наименование Файл Версия Размер
РисункиВSQL.epf 312
.epf 8,51Kb
15.03.10
312
.epf 8,51Kb Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. ПСВ (ПСВ) 15.03.10 13:25

use tempdb

CREATE TABLE myTable(FileName int,
Document varbinary(max))
GO

insert myTable(Filename,Document)
select 1,null

GO

UPDATE myTable
SET Document = (
SELECT *
FROM OPENROWSET(BULK 'D:\картинка\14.jpg', SINGLE_BLOB)AS x )
WHERE FileName = 1;
GO

select * from mytable


asspid_1c; Dimasik2007; +2 Ответить 1
2. Ivon (Ivon) 15.03.10 13:38
(1). Интересное решение. Не знал. А 1С как воспримет банные из varbinary?
3. Артем Титеев (a_titeev) 15.03.10 17:15
ИМХО, все-таки правильнее было бы использовать не nvarchar-поле, а image...
кстати тогда получаем еще одно преимущество - можно хранить, например, различные документы (doc, .xls, .ppt, .txt, .html, .pdf,...), а для них можно применить индексирование с помощью фильтров и использовать full-text search для поиска по содержимому документов...
хранение в nvarchar этого кажись не позволит, ибо сказано было в документации: "Formatted text strings, such as Microsoft® Word™ document files or HTML files, cannot be stored in character string or Unicode columns because many of the bytes in these files contain data structures that do not form valid characters."
4. Ivon (Ivon) 15.03.10 18:19
(3). Я использую Base64Строка(Картинка.ПолучитьДвоичныеДанные()). А там можно любые двоичные данные в виде строки представить.
5. Артем Титеев (a_titeev) 15.03.10 18:49
(4). Так это и понятно, но лучше бы как-нибудь без Base64... Искусственно размер увеличивается, во первых. Во вторых, если все таки хранить что нибудь типа документов, как я писал ранее, теряется возможность использования полнотекстового поиска по содержимому внутри сиквельной таблицы.
Можно попробовать через временные файлы... Типа так: StoredProc заводишь, которая содержимое image сливает в файл с заданным именем, а ты этот файл ДвоичнымиДанными..., и делаешь что нада... или же сразу картинку на основании файла сделать можно, если это картинка...
подобным образом сделал как то хранение документов, которые потом были доступны в 1с и одновременно с этим на сайтике... правда проект развития не получил, и все наработки непонятно где... скорее всего их и нет уже...
но вообще, для простых вещей конечно и так достаточно...
6. Ivon (Ivon) 15.03.10 18:56
(5). Надо будет попробовать. Просто с Base64 вроде как понятнее.
7. Ivon (Ivon) 16.03.10 10:56
Попробовал ложить в двоичном виде - ложить получилось, а вот с чтением проблемы, конструкция
Новый Картинка(RecordSet.Fields(0).Value)

выдает ошибку
Ошибка при вызове конструктора (Картинка): Несоответствие типов (параметр номер '1')

Как побороть - понятия не имею. Если кто-то знает (без сохранения в промежуточный файл), просьба отпостить. Пока вижу единственный рабочий вариант с Base64Строка.
8. Роман Зиновьев (Широкий) 16.03.10 14:18
9. Артем Титеев (a_titeev) 16.03.10 14:47
(8). Да-да. Байка про "неиспользование" типа image в будущих версиях есть и я это видел... действительно рекомендуется varbinary(max)... но в том числе и по личному опыту также знаю о различии в скоростях при работе с image и varbinary(max)... тынц

в принципе в 2008 есть уже и varbinary(max) filestream - можно поюзать его... вроде как это уже именно для подобных целей и будет оптимально с точки зрения производительности. сам не пробовал, руки не доходили, попробую как нибудь позже...

(7). Мало того, скорее всего то что залилось в базу - уже не картинка :( ...
10. Роман Зиновьев (Широкий) 16.03.10 14:54
11. Ivon (Ivon) 16.03.10 14:55
(9). То есть на текущий момент лучше Base64Строка никто ничего работающего предложить не может...
12. Артем Титеев (a_titeev) 16.03.10 15:04
ща, отобьюсь он назойливых... поеду домой, попробую сырцы поискать... sql какой? может правда на filestream переделать?
13. Ivon (Ivon) 16.03.10 15:07
(9). То есть на текущий момент лучше Base64Строка никто ничего работающего предложить не может...
Можно, конечно использовать Stream, но здесь мы упираемся в необходимость сохранения файла на диск. В принципе, каждый из вариантов имеет свои плюсы и минусы, в мое случае плюс - это отсутствие необходимости вначале писать файл на диск, а минус - картинка занимает больше места, потому что вначале перекодируется с помощью Base64Строка.
Вариант с varbinary в данном случае полностью противоположный моему: необходимость сохранения картинки на диск перед тем, как ее прочитать в поле картинки, но картинка в базе будет занимать меньше.
14. Артем Титеев (a_titeev) 16.03.10 15:28
(13). да никуда мы не упираемся... разум коллективный. эффект синергии... придумать можно чё нибудь...
15. Андрей М (_Z1) 16.03.10 19:34
Хранить файл в бд конечно хорошо но есть одно но УРБД.

Я считаю что можно воспользоваться моей компонентой по хранению
бинарных файлов в строке. Это лучше чем Base64Строка
компонента и обсуждение здесь
Преобразование картинки в строку
17. Ivon (Ivon) 17.03.10 10:21
(16). Немного не по теме. Здесь обсуждается не вытягивание картинки из базы 1С в стороннее приложение, а сохранение изображений в отдельной MSSQL базе непосредственно из 1С и чтение этих изображений непосредственно в 1С.
18. Артем Титеев (a_titeev) 17.03.10 13:00
(13). н-да... нашел таки сырцы... ну и бред же я писал года полтора назад... ;) шутка...
да все, естественно через файлы... отличие только в том что через OPENROWSET заливались сразу все доки в папке... а для чтения тот же стрим и в файл... стрим нужен был видимо для того чтоб на локальной машине сохранять...
но меня оправдывает то, что работа была именно с документами, а не с картинками, а там точно вариантов нет - только сохранение в темпарь... итак, дело в том, что тип COMSafeArray который ты получаешь на выходе с RecordSet.Fields("...").Value нада в виде типа Картинка получить... напрашивается что то типа ВК слепить по этому поводу... конечно если существует возможность тип Картинка или ДвоичныеДанные из нее вернуть... можно ли, не знаю...
(15). наверное от специфики проекта зависит... в конце концов РБД не везде. да и дело то не только в хранении, а прежде всего в доступе к внешней базе для получения двоичных данных без промежуточных поползновений по жесткому диску... это может быть просто база внешнего приложения, вполне независимого от1с... строка - хорошо, но недостаточно для меня было, т.к. нужно было и документы не испортить (которые в отдельной системе использовались) и в 1с их как то поиметь...
19. Ivon (Ivon) 17.03.10 13:10
(18). Согласен, если нужно использовать эти файлы не только в 1С, тогда только в бинарном виде сохранять. У меня случай проще, мне нужно использовать файлы только в 1С 8, поэтому Base64 выглядит привлекательнее, не нужно пользоваться временными файлами.
20. Александр Курганов (san4o) 20.03.10 11:51
Для решения задачи сохранения фотографий во внешней базе данных есть внешняя компонента "Фотоархив". Делалась для работы с фотографиями сотрудников в проекте учета рабочего времени. Работает под 7.7 и 8.1.
База данных - SQL или файл Access (*.mdb). Можно использовать для сохранения любой информации, не только файлы с картинками. Например *.mp3 или *.doc. ВК сама создает базу данных в SQL и таблицу для сохранения. Можно задавать имя таблицы. Таблиц может быть сколько угодно.
Объект сохраняется и извлекается из базы по произвольно сформированному ID. В комплекте поставки пример привязки фотографий по внутреннему ID объекта в 1С.
Есть демо-версия http://www.wbp-sar.ru/joomla/index.php?option=com_content&view=article&id=20:-qq&catid=12:2009-10-08-11-25-36&Itemid=37
21. Ivon (Ivon) 22.03.10 09:25
(20). 1) Сайт то-ли не работает полностью, то-ли о нем забыли.
2) Похоже ВК платная, тогда зачем платить деньги, если мой работающий пример бесплатный и тоже позволяет хранить любой файл.
3) Любая ВК требует регистрации ее с правами админа. Мой пример не использует ВК, поэтому будет работать сразу.
22. Allexey (alex_4x) 18.06.10 17:53
А будет он работать с базой на postgres ?
23. Ivon (Ivon) 18.06.10 18:33
(22). Именно данная обработка нет, но если в ней переделать строку подключения и строки запросов под postgres, то, я уверен, оно заработает.
24. Trakt0risT Trakt0risT (Trakt0risT) 15.09.10 11:21
Всё бы не чего, но картинку большого размера не получится преобразовать в Строку (Base64Строка ) что делать? ((( есть выход?
25. Ivon (Ivon) 15.09.10 13:04
(24). Большого - это какого? Я засовывал фотки 8-10 мегапикселей.
26. Trakt0risT Trakt0risT (Trakt0risT) 15.09.10 13:49
Размером более 50 мегабайт!
27. Ivon (Ivon) 15.09.10 14:07
(26). Может просто долго пишется... Или ошибку выдает?
28. Trakt0risT Trakt0risT (Trakt0risT) 15.09.10 14:37
Именно ошибку выдает! говорить что слишком большой размер. приэтом пользовался всеми возможными методами преобразования в строку. не помогает! (
решил проблему следующим методом:
Stream=Новый COMОбъект("ADODB.Stream");
Stream.Type=1;
Stream.Open();
Stream.LoadFromFile(FileData1);
29. Сергей Сивак (legalas84) 08.12.11 15:41
Спасибо огромное. помогла обработка!
30. Yalo (yalo) 13.12.11 12:01
Использовала данную обработку как основу для своей обработки. Очень полезная вещь, помогла очень. Спасибо!
31. Ivon (Ivon) 13.12.11 12:04
(29), (30). У меня в профиле есть статья по хранению рисунков в базе без преобразования в Base64Строка. Работает быстрее и места в БД рисунки занимают меньше.
32. KV1s (KroVladS) 08.08.12 16:51
(28) Trakt0risT,
Можно по подробней, Вы строку передаёте потоком?

(22) alex_4x, (25) Ivon,
Пытаюсь адаптировать для PostgreSQL. Преоброзование в Base64Строка файлов 8МБ проходит нормально, но при выполнении КомандаSQL.Execute(); либо ругаеться на надостаток памяти либо валиться платформа.
33. Ivon (Ivon) 08.08.12 16:57
Вообще с Postgre очень странно работает. У меня, например, не работает выгрузка базы по расписанию. 1С просто вываливается с критической ошибкой. С MSSQL все нормально. Да и перестал я использовать 1С-ное поле картинки. Написал свою компоненту на C#, она и ложит рисунки в базу и отображает.
34. KV1s (KroVladS) 08.08.12 17:08
Пытался адаптировать под PostgreSQL несколько вариантов файловых хранилишь которые нашёл на infostart.ru всё закончилось неудачай. Хранить через Base64Строка единственное что удалось заставить работать и то толко для небольших файлов :(
35. Александр (Alexander78) 08.08.12 17:50
а если тип данных в БД MySql Blob можно напрямую прочитать из 1С (без временного файла)?
36. Invaa (Invaa) 21.05.13 15:42
Раз речь идет о MS SQL, то почему просто не пользоваться штатным механизмом файловых групп? И не нужно никакие сторонние базы создавать. Хочешь хоть каждый справочник или документ на отдельной дисковой подсистеме храни...
37. Ivon (Ivon) 21.05.13 17:13
(36) Это Вы про какой штатный механизм упомянули? Что-то никто из моих коллег не в курсе...
38. Алексей Соловьев (Silenser) 31.10.13 08:37
(37) Ivon, Механизм файловых групп позволяет разделить одну базу данных, на несколько физических файлов данных. Это позволяет разнести одну БД на отдельные дисковые массивы, что поможет решить проблему свободного места и/или производительности. Но, если мне не изменяет память, то при реструктуризации 1С создает копию таблицы, вносит в нее изменения, переносит данные, а затем, удаляет исходную. Создание происходит в дефолтной файловой группе. Таким образом, если я не ошибаюсь, то разделение внутри базы 1С живет до первого обновления, затрагивающего структуру метаданных.
39. Ivon (Ivon) 31.10.13 11:28
(38) Silenser.
Я понял. Вопрос был как раз в том, чтобы хранить картинки именно в отдельной базе. Кроме того, хранение в 1С-овской базе занимает, похоже, столько же места, сколько и в отдельной базе MSSQL с использованием Base64Строка, как описано в этой строке, поэтому именно этот механизм в моей конфе не используется, а используется вот этот http://infostart.ru/public/77329/
demart-omsk; FaKer1980; +2 Ответить
40. Ivon (Ivon) 20.09.16 12:38
Можно немного подправить код на SQL и саму обработку, следующим образом: создать на SQL хранимую процедуру, которая будет принимать Base64 и перекодировать его обратно в binary и ложить в базу уже двоичные данные, а так же вьюшку, которая будет делать обратное преобразование. Кстати, вьюшку можно прицепить, как внешний источник данных и впоследствии данные выбирать простым запросом 1С. В коде в 1С соответственно поменять вызов Insert на вызов хранимой процедуры, а вместо select использовать либо вьюшку в запросе либо вьюшку, как связанный источник данных.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа