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

Запись во внешние источники данных MySQL

Запись во внешние источники данных MySQL
Я
   Impuls20_03
 
12.10.20 - 14:56
Есть база на MySQL подключаю ее как внешний источник данных, импортирую таблицы. В таблице первичный ключ это varchar(100), автоинкремента нету. Проблема возникает когда я пытаюсь создать запись. Появляется ошибка: Описание: [MySQL][ODBC 8.0(w) Driver][mysqld-8.0.21]Truncated incorrect INTEGER value: '0000AD530FA3'
Где 0000AD530FA3 - это то, что я хочу записать в ключевое поле.

Если указать во внешнем источнике другое поле в качестве ключевого, но которое можно преобразовать в Integer - то запись проходит нормально. Нашел на мисте такую же проблему, но решения там так и не нашел: Внешние источники данных запись через 1с

Возможно есть какие-нибудь мысли по этому поводу?
   МихаилМ
 
1 - 12.10.20 - 15:10
для записи ВИД не все драйвера MySQL подходят.
INTEGER - это 2 байта. в вашей ерунде (0000AD530FA3) точно больше.
как MySQL догадается, что  '0000AD530FA3'?
   МихаилМ
 
2 - 12.10.20 - 15:11
что  '0000AD530FA3' - число ?
   Impuls20_03
 
3 - 12.10.20 - 15:22
(1) На MySQL ключевое поле - это строка 100 символов. Я вместо 0000AD530FA3 - могу написать: HelloWorld123
К тому же я через тот же драйвер, только через ADODB.Command. Пишу SQL запрос Inser Into, где пишу все тоже самое. И этот запрос прекрасно отрабатывает и добавляет запись в таблицу.
   arsik
 
4 - 12.10.20 - 15:29
(3) А если это поле совсем не указывать при инсерте?
   Impuls20_03
 
5 - 12.10.20 - 15:34
(4) Первую запись запишет, вместо этого поля запишется 0, вторая запись не пройдет - будет ругаться на дублирующую запись. Если вместо текстового ключа писать числа - все будет записываться корректно.
   arsik
 
6 - 12.10.20 - 15:41
(5) может все таки это поле не символьное?
   Impuls20_03
 
7 - 12.10.20 - 15:47
(6) Хорошая попытка, но нет ))
https://ibb.co/kxtCwky
https://ibb.co/rsLFNtj
   Impuls20_03
 
8 - 13.10.20 - 08:52
В общем включил логирование запросов на MySQL. Вот запрос, прилетающий от 1с.
INSERT INTO cardTemp  (idcard,
                        idcardgroup,
                        idclient,
                        number,
                        validitydatebeg,
                        validitydateend,
                        cardSum,
                        crc,
                        blocked,
                        ownerStoreId,
                        multiplicator,
                        multiplicatorbeg,
                        multiplicatorend,
                        multiplicatorcurrent,
                        lastKnownBonusBalance,
                        lastKnownBonusBalanceDate,
                        pincode,
                        cardstatus,
                        discountpercent,
                        purchases,
                        `update_time`,
                        status,
                        accountNumber) 
VALUES(LAST_INSERT_ID('0000AD52FFA3'),
        '1',
        '1958',
        'B10000AD52FFA301',
        NULL,
        NULL,
        '0',
        NULL,
        NULL,
        NULL,
        '0',
        NULL,
        NULL,
        '0',
        NULL,
        '0001-01-01 00:00:00',
        '',
        '1',
        '0',
        '0',
        '2020-10-13 08:35:35',
        NULL,
        NULL)
   Impuls20_03
 
9 - 13.10.20 - 08:58
В общем теперь вопрос. Можно ли 1с заставить не вставлять LAST_INSERT_ID в запрос?
   VladZ
 
10 - 13.10.20 - 09:25
Сделай поле с первичным ключом числовым.
   Impuls20_03
 
11 - 13.10.20 - 09:34
(10) Если бы я мог. Мне разработчики этой базы голову открутят, если я начну в ней что-то менять. К сожалению мне надо именно строку туда записывать.
   arsik
 
12 - 13.10.20 - 09:37
(11) У тебя во внешнем источнике данных случаем функции не появились?
   Impuls20_03
 
13 - 13.10.20 - 09:40
(12) Нет. Все таблицы. Функций нету.
   Василий Алибабаевич
 
14 - 13.10.20 - 09:41
(12) Вообще то LAST_INSERT_ID() это встроенная функция mysql.
   Impuls20_03
 
15 - 13.10.20 - 09:45
(14) Да я в курсе. Ее включает 1с-ка для всех ключевых полей, независимо от их типа. Вообще очень похоже на баг.
   Василий Алибабаевич
 
16 - 13.10.20 - 09:46
+ (14) И не нужно хотеть в idcard что-то записать. Оно само. Это поле нужно пропустить и в запрос не передавать. И буитваммногасчастия
   Impuls20_03
 
17 - 13.10.20 - 09:54
(16) Идея класс, но мне как раз таки туда нужно записать. Если бы мне оно не надо было, я бы, естественно, так и сделал.
   novichok79
 
18 - 13.10.20 - 10:07
первое, что приходит на ум:
1. городить хранимую процедурку на стороне mysql и дергать ее из 1С.
2. исключить id из первичных ключей в свойствах таблиц внешнего источника данных в 1С.
   Impuls20_03
 
19 - 13.10.20 - 10:20
(18) По поводу 1. Тут однозначно нет. Лезть в структуру БД мне никто не даст.
По поводу 2 сейчас копаю в данном направлении. Правда если я убираю все ключи - Таблица становится необъектной. И теперь я не могу вызвать метод СоздатьОбъект(). Наверное можно создавать набор записей. Но записей много и они каждый раз будут перезаписываться. Это резко будет нагружать сервере MySQL.
   experimentator76
 
20 - 13.10.20 - 10:22
(19) ADO
   Impuls20_03
 
21 - 13.10.20 - 10:28
(20) Если не найдется решения - видимо придется через ADO.
   arsik
 
22 - 13.10.20 - 10:57
(21) Может тебе нужно перед записью УстановитьСсылкуНового для объекта сделать?
   Impuls20_03
 
23 - 13.10.20 - 11:02
(22) Увы.((
   arsik
 
24 - 13.10.20 - 11:04
(23) Это что значит?
   Impuls20_03
 
25 - 13.10.20 - 11:15
(24) Это значит не прокатило. Он просто устанавливает ссылку на еще не записанный объект. И потом ее можно присвоить какому-нибудь реквизиту на форме.
   Impuls20_03
 
26 - 13.10.20 - 11:19
Окей. Давайте переформулируем.
Я создаю менеджер записи. Все пишется как надо, но, почему-то вся таблица очищается и остается только последний записанный элемент. Очевидно что я где-то косячу, но не могу понять где
Для каждого карта из СписокОтсутствующихКарт Цикл
    новаяКарта                                 = ВнешниеИсточникиДанных.Artix.Таблицы.cardTemp.СоздатьМенеджерЗаписи();
    новаяКарта.idcard                        = карта.ИД;
    новаяКарта.idcardgroup                    = 1;               //Жестко определено - карты сотрудников

    новаяКарта.idclient                        = Формат(карта.БонуснаяКартаКод, "ЧН=0; ЧГ=");
    новаяКарта.number                        = "B1"+карта.ИД+"01";
    новаяКарта.blocked                        = Null;
    новаяКарта.cardstatus                    = 1;    //0 - начисление; 1 - начисление и оплата; 2 - заблокирована; 3 - только оплата

    новаяКарта.Записать(Истина);
КонецЦикла;

   arsik
 
27 - 13.10.20 - 11:43
(26) Попробуй СоздатьКлючЗаписи
   Impuls20_03
 
28 - 13.10.20 - 11:50
(27) Пробовал. Не работает это. Точнее ключ то он создает, а что с ним дальше делать непонятно. У менеджера записи есть метод Прочитать(), который, по идее, должен читать согласно установленного ранее ключа. Но опять таки он не принимает никаких параметров
   arsik
 
29 - 13.10.20 - 11:56
(28) Мне кажется нужно
СоздатьКлючЗаписи()
прочитать()
ЗаполнитьОстальные поля
Записать()
   Impuls20_03
 
30 - 13.10.20 - 12:05
(29) Не работает. То что СоздатьКлючЗаписи() ни на что не влияет это раз. Во вторых. Если в Таблице только одна запись - то прочитать() - возвращает ее, если в таблице 2 и более записи то появляется ошибка.  Запись не верна! Набор записей, принадлежащий менеджеру записи должен содержать ровно 1 запись. Ну т.е. что-то явно делается не так.
 
 Рекламное место пустует
   arsik
 
31 - 13.10.20 - 12:07
(30) Код приведи
   arsik
 
32 - 13.10.20 - 12:08
+(31) Потому что ключ записи не указан.
   experimentator76
 
33 - 13.10.20 - 12:12
(26) набор записей создай и наложи отбор
   Impuls20_03
 
34 - 13.10.20 - 12:30
(31)
стр = новый Структура("idcard", карта.ИД);
ключЗаписи = ВнешниеИсточникиДанных.Artix.Таблицы.cardTemp.СоздатьКлючЗаписи(стр);
новаяКарта                         = ВнешниеИсточникиДанных.Artix.Таблицы.cardTemp.СоздатьМенеджерЗаписи(); 
новаяКарта.idcard                    = карта.ИД;
новаяКарта.Прочитать();
        
новаяКарта.idcard                    = карта.ИД;
новаяКарта.idcardgroup                    = 1;               //Жестко определено - карты сотрудников

новаяКарта.idclient                    = Формат(карта.БонуснаяКартаКод, "ЧН=0; ЧГ=");
новаяКарта.number                    = "B1"+карта.ИД+"01";
новаяКарта.blocked                    = Null;
новаяКарта.cardstatus                    = 1;    //0 - начисление; 1 - начисление и оплата; 2 - заблокирована; 3 - только оплата

новаяКарта.Записать(Ложь);

новаяКарта.idcard = карта.ИД; - без этого тоже не работает
   Impuls20_03
 
35 - 13.10.20 - 12:33
(33) Да пробовал я набор создавать. Отбор не накладывается.
Набор = ВнешниеИсточникиДанных.Artix.Таблицы.cardTemp.СоздатьНаборЗаписей();
Набор.Отбор.idcard.Установить(карта.ИД);        // Не работает не видит поля idcard

Набор.Отбор.Добавить("idcard");                // 1C сообщает: Метод не доступен для данного объекта
   novichok79
 
36 - 13.10.20 - 12:55
(35) отбор не накладывается, потому как во внешних источниках если таблица необъектная, у нее должны быть измерения.
а их у тебя нету. значит когда идет запись, оно сначала делает delete where измерение1 = значениеизмерения1
а потом insert. так как измерений нет, то просто делается delete from твоятаблица, делай через ADO, раз даже хранимку нельзя.
   Impuls20_03
 
37 - 13.10.20 - 12:58
(36) Да я уже понял что глухо. Уже засел за ADO
   arsik
 
38 - 13.10.20 - 13:00
(36) Так у него же есть измерение - idcard, уникальное. Возможно при подключении внешнего источника что то неправильно указал?
поле ключа то указано?
https://i.imgur.com/VpMOYH6.png
   novichok79
 
39 - 13.10.20 - 13:01
(38) возможно 1С хреново с MySQL работает. я пробовал подрубиться к базе на MySQL и сделать запрос в конструкторе запросов 1С - там тупо удобнее и 1Сина валилась с непонятной ошибкой. я забил разбираться.
   novichok79
 
40 - 13.10.20 - 13:02
(38) надо трейсить запросы которые шлет 1Сина в MySQL, без них сложно что-то сказать.
   Impuls20_03
 
41 - 13.10.20 - 13:42
(40) Я же выкладывал запрос который 1с отправляет. Она в ключевое поле вставляет LAST_INSERT_ID('Текст ключа'). И MySQL на этом моменте сваливается. А если в свойствах таблицы 1с убрать все ключи, то таблица становится необъектной и получается то, что Вы и описали: 1с Шлет delete from cardTemp. Что собственно говоря и очищает всю таблицу. Остается единственный вариант - это создавать НаборЗаписей. Но его я использовать не хочу, потому как он сперва выгружает все записи из таблицы, а после того как его записать он снова их вгружает в СУБД. А это нагрузка и вообще ай яй яй так делать без отбора. А отбор сделать не получается потому что нет измерений)). Замкнутый круг
INSERT INTO cardTemp  (idcard,
                        idcardgroup,
                        idclient,
                        number,
                        validitydatebeg,
                        validitydateend,
                        cardSum,
                        crc,
                        blocked,
                        ownerStoreId,
                        multiplicator,
                        multiplicatorbeg,
                        multiplicatorend,
                        multiplicatorcurrent,
                        lastKnownBonusBalance,
                        lastKnownBonusBalanceDate,
                        pincode,
                        cardstatus,
                        discountpercent,
                        purchases,
                        `update_time`,
                        status,
                        accountNumber) 
VALUES(LAST_INSERT_ID('0000AD52FFA3'),
        '1',
        '1958',
        'B10000AD52FFA301',
        NULL,
        NULL,
        '0',
        NULL,
        NULL,
        NULL,
        '0',
        NULL,
        NULL,
        '0',
        NULL,
        '0001-01-01 00:00:00',
        '',
        '1',
        '0',
        '0',
        '2020-10-13 08:35:35',
        NULL,
        NULL)

   arsik
 
42 - 13.10.20 - 13:55
(41) Так надо подцепить, в источники, таблицу как необъектную, но с ключем.
   Impuls20_03
 
43 - 13.10.20 - 15:05
(42) Вот я лопух. Точно. Такой вариант заработал как надо. Причем как с набором записей, так и с менеджером записи. Как говорится век живи, век учись.

набор = ВнешниеИсточникиДанных.Artix.Таблицы.cardTemp.СоздатьНаборЗаписей();
набор.Отбор.idcard.Установить(карта.ИД);
набор.Прочитать();
новаяКарта = набор.Добавить();
....
набор.Записать(Истина);


новаяКарта = ВнешниеИсточникиДанных.Artix.Таблицы.cardTemp.СоздатьМенеджерЗаписи();
новаяКарта.idcard = карта.ИД;
новаяКарта.Прочитать();
....
новаяКарта.Записать(Истина);

   experimentator76
 
44 - 13.10.20 - 18:01
(43) Семен-семеныч! Это как бы подразумевалось, что ты не будешь мешать программе работать.
при добавлении таблицы 1С сама по большей части все делает что нужно...


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