Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Запрос к SQLlite из 1С

Запрос к SQLlite из 1С
Я
   neomarat
 
05.08.21 - 17:29
Направьте в правильную сторону. Мой код:
SQLiteObject = Новый COMОбъект("ADODB.Connection");
SQLiteConnectionString = "DRIVER=SQLite3 ODBC Driver;Database=" + ФайлБД + ";";
SQLiteObject.Open(SQLiteConnectionString);
SQLiteRS = Новый COMОбъект("ADODB.Recordset");
Запрос =  "INSERT INTO Goods (_id,_name,_jpg,_text) VALUES (" + "'" + _id + "'," + "'" + _name + "',"  + "@jpg" + ","+ "'" + _text + "'" + ")";
SQLiteRS = SQLiteObject.Execute(Запрос);

Как передать параметр @jpg - файл в поле типа BLOB ?
   Garykom
 
1 - 05.08.21 - 17:29
не буду предлагать свое решение ибо набегут и охают
   neomarat
 
2 - 05.08.21 - 17:30
(1) любые надо!
   Kassern
 
3 - 05.08.21 - 17:30
(2) готовы уже писать микросервисы на го?)
   Ёпрст
 
4 - 05.08.21 - 17:31
(0) разве что через обёртку
   Kassern
 
5 - 05.08.21 - 17:31
(1) приведите пример как на го решается такая задача "Как передать параметр @jpg - файл в поле типа BLOB"
   neomarat
 
6 - 05.08.21 - 17:31
(3) не... мне бы 1с победить...
   Ёпрст
 
7 - 05.08.21 - 17:34
Ну, не скуль лайт, но принцип тот же:
Запись данных типа BLOB в SQL Server через 1С
   Garykom
 
8 - 05.08.21 - 17:35
   Garykom
 
9 - 05.08.21 - 17:37
   Garykom
 
10 - 05.08.21 - 17:42
   neomarat
 
11 - 05.08.21 - 17:50
(7) там через хранимую процедуру - у меня ее нет.
(8)-(10) - это я вообще не понял... ))
   Garykom
 
12 - 05.08.21 - 17:51
(10)+ хотя типовой https://github.com/mattn/go-sqlite3/ тоже оказывается может, банальным образом через структуру с []byte
https://github.com/mattn/go-sqlite3/blob/3392062c729d77820afc1f5cae3427f0de39e954/sqlite3_test.go#L1745
просто пример запрятан и отдельно с блобами не вынесен
   Garykom
 
13 - 05.08.21 - 17:52
(11) это (3)
   Garykom
 
14 - 05.08.21 - 17:52
(11) если знаешь Golang то час примерно нужен чтобы наваять прокладку
   neomarat
 
15 - 05.08.21 - 17:54
(14) через 1С разве никак?
   Garykom
 
16 - 05.08.21 - 17:56
(15) из 1С никак, если ВИД не может

ADO (Новый COMОбъект("ADODB.Connection")) это тоже прокладка уже готовая, просто ты ее из 1С юзаешь
если ее нет (например фреш или линукс/андроид) то привет
   neomarat
 
17 - 05.08.21 - 17:58
(15) а что значит вид не может?
   Garykom
 
18 - 05.08.21 - 17:59
(17) Внешний Источник Данных
   neomarat
 
19 - 05.08.21 - 17:59
Задача - вогнать файл картинки с диска в поле записи SQL.
Мне кажется тривиальная задача должна быть?
   Garykom
 
20 - 05.08.21 - 18:04
(19) замени sqlite на например mongo или redis (или еще нечто из списка https://db-engines.com/en/ranking)
и задача останется тривиальной?
   Garykom
 
21 - 05.08.21 - 18:04
   Garykom
 
22 - 05.08.21 - 18:08
(19) можно base64 и в текстовое поле если база твоя
   neomarat
 
23 - 05.08.21 - 18:10
(22) База моя - но вот как потом ее обратно?
   Garykom
 
24 - 05.08.21 - 18:12
(23) точно так же, 1С умеет с base64 и двоичныеданные
   Garykom
 
25 - 05.08.21 - 18:12
(24)+ но это потери накладные и скорости и места
   NorthWind
 
26 - 05.08.21 - 18:27
(19) Тривиальная для языков, где работа с двоичными данными подразумевается с рождения и есть все инструменты для этого. Для 1С не особо, потому как у нее это не с рождения, а нашлепка сбоку на "отвяжись".
   Garykom
 
27 - 05.08.21 - 18:42
(26) да меня убивает насколько неудобен и сложен в 1С механизм ВК
казалось бы ну дай платформенную возможность обычные c-shared dll юзать и сразу все стало бы сильно проще
   neomarat
 
28 - 05.08.21 - 19:22
Так если она умеет двоичные данные - то наверное может как то их передать в запрос insert?
   acht
 
29 - 05.08.21 - 20:46
(27) Что соскочить с 1С не получается, так хоть обосрем её?
   Garykom
 
30 - 05.08.21 - 21:17
(29) т.е. ты можешь легко решить проблему ТС из (0)?
ну покажи как
я свое решение уже выкатил
 
 
   neomarat
 
31 - 05.08.21 - 21:29
двоичные данные из 1С и BLOB поле в SQL - не одно и тоже?
   neomarat
 
32 - 05.08.21 - 21:30
Пробую так еще:

cmd = Новый COMОбъект("ADODB.Command");
    cmd.CommandText = "INSERT INTO Goods (_id,_name,_jpg,_text) VALUES ("+ "@Id" + "," + "@Name" + "," + "@Jpg" + ","+  "@Text" + ")";
    cmd.CommandType = 1;
    cmd.NamedParameters = "True";
    cmd.Parameters.Append(cmd.CreateParameter("@Id",200,1,100));
    cmd.Parameters.Append(cmd.CreateParameter("@Name",200,1,100));
    cmd.Parameters.Append(cmd.CreateParameter("@Jpg",128,1,16));
    cmd.Parameters.Append(cmd.CreateParameter("@Text",200,1,100)); 
    cmd.ActiveConnection = SQLiteObject;
    
    Для Каждого Выборка ИЗ ТЗ Цикл
        //найдем изображение

        Если ЗначениеЗаполнено(Выборка.JPG) Тогда
            //ФайлКартинки = Новый ДвоичныеДанные("E:\Backup_Arhiv\DropBox\" + Выборка.JPG);

            ФайлКартинки = Новый Файл("E:\Backup_Arhiv\DropBox\" + Выборка.JPG);
        Иначе
            ФайлКартинки = "";
        КонецЕсли;
        
        cmd.Parameters("@Id").Value = СОКРЛП(Выборка.ID);
        cmd.Parameters("@Name").Value = СОКРЛП(Выборка.NAME);
        cmd.Parameters("@Jpg").Value = ФайлКартинки;
        cmd.Parameters("@Text").Value = СОКРЛП(Выборка.TEXT);
        
        cmd.Execute();
    КонецЦикла;
    SQLiteObject.Close();
    SQLiteObject = "";
   neomarat
 
33 - 05.08.21 - 21:31
Валится с ошибкой: Произошла исключительная ситуация (ADODB.Parameter): Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом.
   neomarat
 
34 - 05.08.21 - 21:31
и с двоичными данными и с файлом
   NorthWind
 
35 - 05.08.21 - 21:35
(33) посмотри в сторону прокладки на VBS. Если мне склероз не изменяет, там можно в ADO Stream зачитать JPEG и потом нормально в качестве параметра передать.
   NorthWind
 
36 - 05.08.21 - 21:37
когда Гарик агитирует в сторону затычек на го, он по сути вполне прав, потому что у 1С это все реально не по-нормальному... и тут речь не про "обосрать", а просто констатация факта
   NorthWind
 
37 - 05.08.21 - 21:45
Вот работа с большим текстом (МЕМО) в VBS.
Может быть, поможет как-то

Sub AssignADOParam (Cmd, ParType, ParName, ParValue, ParDirection)

    on error resume next
    Set Param = Cmd.Parameters.Item (ParName)

    if err then
        ' Была ошибка, т.е. параметр не найден - создаем новый
    Cmd.Parameters.Append _
    Cmd.CreateParameter (ParName, ParType, ParDirection, 0, ParValue)
    else
        ' Параметр найден
    Param.Type      = ParType
    Param.Direction = ParDirection
    Param.Value     = ParValue
    end if

End Sub

Function CreateCommand (CommandText)

        Set cmd = CreateObject ("ADODB.Command")
        cmd.ActiveConnection = acMain
    cmd.CommandText = CommandText
    Set CreateCommand = cmd

End Function

Sub PutCorrText (SourceDocGUID, CorrText)

    Set ts = CreateObject ("ADODB.Stream")
    ts.Type = 2
    ts.Open
    ts.WriteText CorrText
    Set bs = CreateObject ("ADODB.Stream")
    bs.type = 1
    bs.Open
    ts.Position = 0
    ts.CopyTo bs
    bs.Position = 0    
    BinaryData = bs.Read ()

    Set cmdInsText = CreateCommand (_
    "insert into CORRTEXTS (VGUID, INFO) values (:VGUID, :INFO)")

    AssignADOParam cmdInsText, adTypeGUID, ":VGUID", BraceGUID (SourceDocGUID), 1

    Set Param = cmdInsText.Parameters.Item (":INFO")
    Param.Size = bs.Size
    Param.AppendChunk BinaryData

    cmdInsText.Execute
        
End Sub
   NorthWind
 
38 - 05.08.21 - 21:46
Обратите внимание на функцию AppendChunk. Может быть, с ее помощью получится решить вопрос и без прокладки-скрипта?
   Garykom
 
39 - 05.08.21 - 22:14
(38) да думаю можно через ADODB.Command
   neomarat
 
40 - 06.08.21 - 00:13
Получилось так:
    cmd = Новый COMОбъект("ADODB.Command");
        cmd.CommandText = "INSERT INTO Goods (_id,_name,_text,_jpg) VALUES ("+ "?" + "," + "?" + "," + "?" + ","+  "?" + ")";
        cmd.CommandType = 1;
        cmd.NamedParameters = "True";
        cmd.Parameters.Append(cmd.CreateParameter("@Id",200,1,100));
        cmd.Parameters("@Id").Value = СОКРЛП(Выборка.ID);
        cmd.Parameters.Append(cmd.CreateParameter("@Name",201,1,100));
        cmd.Parameters("@Name").Value = СОКРЛП(Выборка.NAME);
        cmd.Parameters.Append(cmd.CreateParameter("@Text",200,1,1000)); 
        cmd.Parameters("@Text").Value = СОКРЛП(Выборка.TEXT);
        //найдем изображение

        Если ЗначениеЗаполнено(Выборка.JPG) Тогда
            //ФайлКартинки = Новый ДвоичныеДанные("E:\Backup_Arhiv\DropBox\" + Выборка.JPG);

            ФайлКартинки = Новый Файл("E:\Backup_Arhiv\DropBox\" + Выборка.JPG);
        Иначе
            ФайлКартинки = "";
        КонецЕсли;
                
        StreamIn = Новый COMОбъект("ADODB.Stream");
        StreamIn.Type = 1;// В потоке двоичные данные

        StreamIn.Mode = 3;  // Режим работы потока - на чтение и запись

        StreamIn.Open();
        StreamIn.LoadFromFile("E:\Backup_Arhiv\DropBox\" + Выборка.JPG); 
        Рез = StreamIn.Read(); 
        StreamIn.Close();
        
        cmd.Parameters.Append(cmd.CreateParameter("@Jpg",128,1,Рез.GetLength()));
        cmd.Parameters("@Jpg").Value = Рез;

                
        cmd.ActiveConnection = SQLiteObject;

        cmd.Execute();

Но теперь вообще странная проблема: поля _name,_text грузятся BLOB полями, а _id - обычный текст.
Хотя там везде текстовые значения.
Не пойму в чем дело.
   neomarat
 
41 - 06.08.21 - 00:14
При этом картинка тоже BLOB - подгружается как надо...
   NorthWind
 
42 - 06.08.21 - 08:01
(40) cmd.Parameters.Append(cmd.CreateParameter("@Id",200,1,100));
...
        cmd.Parameters.Append(cmd.CreateParameter("@Name",201,1,100));
...
        cmd.Parameters.Append(cmd.CreateParameter("@Text",200,1,1000)); 

а что, ID действительно текст и Name - длинный текст?
Откуда взяты эти 200 и 201?
Какие реальные типы полей в базе? Или у SQLite с типизацией все обстоит не так как у больших СУБД (я не в курсе)?
   NorthWind
 
43 - 06.08.21 - 08:05
201 (adLongVarChar) - это случайно не строка неопределенной длины? Если так то это блоб и есть. Или мемо-поле, как их еще называют. Но это не точно.
   neomarat
 
44 - 06.08.21 - 09:18
(43) да я разные ставил и 200, и 201 и таблицу в коде создавал запросом - все равно БЛОБ
при этом
cmd.Parameters.Append(cmd.CreateParameter("@Id",200,1,100)); - текст
cmd.Parameters.Append(cmd.CreateParameter("@Name",201,1,100)); - BLOB
cmd.Parameters.Append(cmd.CreateParameter("@Text",200,1,1000)); - BLOB

даже так
cmd.Parameters.Append(cmd.CreateParameter("@Name",200,1,СтрДлина(Выборка.NAME))); - BLOB
   neomarat
 
45 - 06.08.21 - 09:27
БЛИННН я понял - кириллицу SQlite распознает как BLOB... Вот блин столько времени убил...
   NorthWind
 
46 - 06.08.21 - 11:47
(45) вот тут не могу ничего посоветовать, я эту СУБД практически не знаю...
   NorthWind
 
47 - 06.08.21 - 15:45
(45) > даже так
> cmd.Parameters.Append(cmd.CreateParameter("@Name",200,1,СтрДлина(Выборка.NAME))); - BLOB
> БЛИННН я понял - кириллицу SQlite распознает как BLOB... Вот блин столько времени убил...

Так в этом примере выше кириллице неоткуда взяться. Там цифры должны быть.
   neomarat
 
48 - 06.08.21 - 16:24
(47) почему цифры? Обычный текст
   NorthWind
 
49 - 06.08.21 - 21:46
(48) Действительно, я не обратил внимание на отсутствие одного параметра в CreateParameter. Value вы присваиваете позже. Я все это делаю в одну строку.


Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.