Запись файла в SQL-базу внешнего приложения

1. Богатырев Артур 127 10.04.17 11:16 Сейчас в теме
Добрый всем день.

Конфигурация Управление Торговлей 11.
Суть вопроса: дописывал начатый до меня модуль обмена информацией с программой "ServiceDesk" (СервисДеск) - чтение данных оттуда (задач - "инцидентов"), а также создание из 1С - новых задач-"инцидентов" в Сервис Деск (это система постановки задач).
Чтение - без вопросов. Создание новых задач - тоже. Проблемы возникли тогда, когда к новому инциденту необходимо стало прикреплять файл с диска. И средствами 1С это записывать в SQL-таблицу базы Сервис Деск. Файлы, прикрепленные к инцидентам Сервис ДЕск, хранятся в отдельной таблице, где ID - номер инцидента, а затем идет поле - сам файл.

Пытался сделать через ADODB.Command. Но при попытке выполнить команду записи все время возвращается ответ SQL, что не совпадает формат.

Т.е. примерно так:
НаборЗаписей = Новый COMОбъект("ADODB.Command");
НаборЗаписей.CommandType = 1;
НаборЗаписей.ActiveConnection = АктивноеСоединение;

НаборЗаписей.CommandText = "INS ERT IN TO [dbo].[vw_FILES] ( [ID], [FILE]";
СтрокаЗначений = " VALUES ( {"+ГУИДИнцидента+"}', + ПолеФайла ") ";

НаборЗаписей.CommandText = НаборЗаписей.CommandText + СтрокаЗначений;
НаборЗаписей.Execute();


В переменной ПОЛЕФАЙЛА у меня сам файл (вида "двоичные данные").
И ошибка... Поле FILE в SQL-таблице имеет тип "image", т.е. вроде как двоичные данные.

При этом чтение файлов из таблиц файлов SQL и их запись на диск, я произвожу легко через Стрим при обработке запроса:

Stream = Новый COMОбъект("ADODB.Stream");
Stream.Type = 1;
Stream.Open();
Stream.Write(СтруктураИзЗапроса.ДанныеФайла);
ИмяФайла = СтруктураИзЗапроса.Имя;
ВремПуть = КаталогВременныхФайлов() + ИмяФайла;
stream.SaveToFile(ВремПуть,2);
Stream.Close();
Stream = Неопределено;

А вот записать обратно не могу. В чем причина? Что не так?
По теме из базы знаний
Найденные решения
15. ImHunter 327 11.04.17 15:13 Сейчас в теме
Поэтому я и не люблю использовать динамически сконструированные запросы с прописанными значениями - их (значения) надо сформатировать в какой-то определенный строковый вид. К тому же, при этом планы запросов не кэшируются. И, теоретически, это дыра в безопасности из-за возможности sql injection.
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. nickpugachev 10.04.17 11:21 Сейчас в теме
А тем же Stream передать не получается?

Ну и вариант с внешним источником попробуйте
3. Богатырев Артур 127 10.04.17 11:37 Сейчас в теме
5. ImHunter 327 10.04.17 12:10 Сейчас в теме
Можно еще попробовать сохранять выполнением ХП. Т.е., обеспечить для 1С интерфейс с передачей строки.
Как развитие варианта, можно сделать внешним источником, как посоветовали в (2).
6. Богатырев Артур 127 10.04.17 13:48 Сейчас в теме
(5)
Можно еще попробовать сохранять выполнением ХП.

И снова просьба расшифровать.
8. ImHunter 327 10.04.17 14:15 Сейчас в теме
(6) Возможно, проблема в том, что не получается в тип image из 1С запросом закинуть.
Нужно попробовать написать хранимую процедуру. У нее на входе пусть будут параметры по-проще - ну тот же УИД и строка, которая будет подставляться внутри процедуры в поле типа image.
Честно говоря, такими преобразованиями не занимался (строки в image). Но, возможно, все и несложно.
7. v3rter 10.04.17 14:11 Сейчас в теме
9. ImHunter 327 10.04.17 17:05 Сейчас в теме
Не, строка нормально в image складывается. Вероятно, дело в передаче УИДа.
Должно быть как-то так:
СтрокаЗначений = " VALUES ( [Апостроф]" + ГУИДИнцидента+"[Апостроф], [Апостроф]" + ПолеФайла + "[Апостроф]) ";
- где вместо [Апостроф] нужно подставить символ апострофа. Так оформил, чтобы заметно было - где что.
10. Богатырев Артур 127 11.04.17 11:44 Сейчас в теме
(9) "Строка нормально в image складывается". Вы бы не могли "чуть подробнее" тут?
У меня как раз ГУИД сбрасывается нормально.
Вы выполнили через процедуру или просто передали запросом? Какого типа (1С-ного) тогда у вас "ПолеФайла"?
11. ImHunter 327 11.04.17 12:05 Сейчас в теме
(10) Да просто создал табличку с полем типа image и запросом вставил в нее запись, где в значении для image указал строку. Запрос выполнился, запись вставилась.
Вообще, как раз на тек момент занимаюсь выгрузкой данных во внеш базу (MSSQL, не 1С). Написал для этого внешку-движок с заточкой на использование ХП для вставки данных. Если интересно - могу выложить. Написано не супер-пупер продуманно и оптимально, т.к. использоваться будет малоразово. Но на 4 - вполне себе.
12. ImHunter 327 11.04.17 12:09 Сейчас в теме
А выложите текст запроса, который пытаетесь выполнить.
13. Богатырев Артур 127 11.04.17 14:57 Сейчас в теме
(12)
В коде 1С:
НаборЗаписей = Новый COMОбъект("ADODB.Command");
НаборЗаписей.CommandType = 1;
НаборЗаписей.ActiveConnection = АктивноеСоединение;

НаборЗаписей.CommandText = " INS ERT IN TO [dbo].[tbl_Files] ([ID], [Link], [Revision], [ItemTypeID], [FileData], [ModifiedByID], [ModifiedOn], [FileSize], [CreatedOn], [CreatedByID]) VALUES ( '{"+ГУИДФ+"}', '"+ИмяФайла+"', 1, '{39A5B367-4A7A-473E-8F74-26977CB6DB67}','{"+ ДвоичФайл +"}', ' "+ АйДиПользователя +" ', getdate(), "+строка(Размер)+", getdate(), '"+ АйДиПользователя +"')";

Здесь:
ДвоичФайл = Новый ДвоичныеДанные(ПутьФайла); - т.е. сами двоичные данные файла.
ГУИДФ - ГУИД нового файла.
ИмяФайла - собственно имя файла.
АйДиПользователя - айди того кто пишет в эту базу.

Затем делаю
НаборЗаписей.Execute();

Запрос отправляется в базу такой:
Скрытый текст запроса


Теперь ругается на неверный синтаксис.
Ошибка записи данных в базу: {Документ.ЗаказКлиента.Форма.ФормаДокумента_СВИ.Форма(5909)}: Ошибка при вызове метода контекста (Execute): Произошла исключительная ситуация (Microsoft OLE DB Provider for ODBC Drivers): [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near ' '.
14. ImHunter 327 11.04.17 15:03 Сейчас в теме
getdate(), 6 768, getdate() - присутствует пробел, нужно отформатировать.
15. ImHunter 327 11.04.17 15:13 Сейчас в теме
Поэтому я и не люблю использовать динамически сконструированные запросы с прописанными значениями - их (значения) надо сформатировать в какой-то определенный строковый вид. К тому же, при этом планы запросов не кэшируются. И, теоретически, это дыра в безопасности из-за возможности sql injection.
16. Богатырев Артур 127 11.04.17 16:16 Сейчас в теме
(15) Ваш совет несколько помог, но ошибка осталась, правда, изменилась:

Ошибка записи данных в базу: {Документ.ЗаказКлиента.Форма.ФормаДокумента_СВИ.Форма(5910)}: Ошибка при вызове метода контекста (Execute): Произошла исключительная ситуация (Microsoft OLE DB Provider for ODBC Drivers): [Microsoft][ODBC SQL Server Driver][SQL Server]INSERT permission denied on object 'tbl_Files', database 'TStoy', schema 'dbo'.
Подозреваю, что правами запрещено писать в эту таблицу?
17. Богатырев Артур 127 11.04.17 16:59 Сейчас в теме
(15) Запись пошла успешно. проблема в том, что теперь в базу пишется строка, а не файл...
18. ImHunter 327 11.04.17 17:19 Сейчас в теме
(17) Гм. А как проявляется эта проблема? Может ее и нет на самом деле?:)
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот