Имя: Пароль:
1C
1С v8
Запрос к SQLlite из 1С
0 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 ?
1 Garykom
 
гуру
05.08.21
17:29
не буду предлагать свое решение ибо набегут и охают
2 neomarat
 
05.08.21
17:30
(1) любые надо!
3 Kassern
 
05.08.21
17:30
(2) готовы уже писать микросервисы на го?)
4 Ёпрст
 
05.08.21
17:31
(0) разве что через обёртку
5 Kassern
 
05.08.21
17:31
(1) приведите пример как на го решается такая задача "Как передать параметр @jpg - файл в поле типа BLOB"
6 neomarat
 
05.08.21
17:31
(3) не... мне бы 1с победить...
7 Ёпрст
 
05.08.21
17:34
Ну, не скуль лайт, но принцип тот же:
Запись данных типа BLOB в SQL Server через 1С
8 Garykom
 
гуру
05.08.21
17:35
9 Garykom
 
гуру
05.08.21
17:37
10 Garykom
 
гуру
05.08.21
17:42
11 neomarat
 
05.08.21
17:50
(7) там через хранимую процедуру - у меня ее нет.
(8)-(10) - это я вообще не понял... ))
12 Garykom
 
гуру
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
просто пример запрятан и отдельно с блобами не вынесен
13 Garykom
 
гуру
05.08.21
17:52
(11) это (3)
14 Garykom
 
гуру
05.08.21
17:52
(11) если знаешь Golang то час примерно нужен чтобы наваять прокладку
15 neomarat
 
05.08.21
17:54
(14) через 1С разве никак?
16 Garykom
 
гуру
05.08.21
17:56
(15) из 1С никак, если ВИД не может

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

я свое решение уже выкатил
31 neomarat
 
05.08.21
21:29
двоичные данные из 1С и BLOB поле в SQL - не одно и тоже?
32 neomarat
 
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 = "";
33 neomarat
 
05.08.21
21:31
Валится с ошибкой: Произошла исключительная ситуация (ADODB.Parameter): Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом.
34 neomarat
 
05.08.21
21:31
и с двоичными данными и с файлом
35 NorthWind
 
05.08.21
21:35
(33) посмотри в сторону прокладки на VBS. Если мне склероз не изменяет, там можно в ADO Stream зачитать JPEG и потом нормально в качестве параметра передать.
36 NorthWind
 
05.08.21
21:37
когда Гарик агитирует в сторону затычек на го, он по сути вполне прав, потому что у 1С это все реально не по-нормальному... и тут речь не про "обосрать", а просто констатация факта
37 NorthWind
 
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
38 NorthWind
 
05.08.21
21:46
Обратите внимание на функцию AppendChunk. Может быть, с ее помощью получится решить вопрос и без прокладки-скрипта?
39 Garykom
 
гуру
05.08.21
22:14
(38) да думаю можно через ADODB.Command
40 neomarat
 
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 - обычный текст.
Хотя там везде текстовые значения.
Не пойму в чем дело.
41 neomarat
 
06.08.21
00:14
При этом картинка тоже BLOB - подгружается как надо...
42 NorthWind
 
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 с типизацией все обстоит не так как у больших СУБД (я не в курсе)?
43 NorthWind
 
06.08.21
08:05
201 (adLongVarChar) - это случайно не строка неопределенной длины? Если так то это блоб и есть. Или мемо-поле, как их еще называют. Но это не точно.
44 neomarat
 
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
45 neomarat
 
06.08.21
09:27
БЛИННН я понял - кириллицу SQlite распознает как BLOB... Вот блин столько времени убил...
46 NorthWind
 
06.08.21
11:47
(45) вот тут не могу ничего посоветовать, я эту СУБД практически не знаю...
47 NorthWind
 
06.08.21
15:45
(45) > даже так
> cmd.Parameters.Append(cmd.CreateParameter("@Name",200,1,СтрДлина(Выборка.NAME))); - BLOB
> БЛИННН я понял - кириллицу SQlite распознает как BLOB... Вот блин столько времени убил...

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