|   |   | 
| 
 | Выборка данных из MS SQL, передача в 1С и их дальнейшая обработка | ☑ | ||
|---|---|---|---|---|
| 0
    
        Gill 03.08.22✎ 13:25 | 
        Всем привет! Возникла необходимость получения данных из базы по учету контроля доступа сотрудников в здании и дальнейшая обработка этих данных в 1С.
 Подключаемся к базе на SQL успешно, но но далее вываливается с ошибкой {ВнешнийОтчет.СКУД_Баулюкс.Форма.ФормаОтчета.Форма(70)}: Ошибка при вызове метода контекста (Execute): Произошла исключительная ситуация (Microsoft OLE DB Provider for ODBC Drivers): [Microsoft][ODBC SQL Server Driver]Истекло время ожидания запроса С значениями ConnectionTimeout и CommandTimeout пробовались играться (выствлять в О, исключать и т.д.). Прошу подсказать, почему данный запрос не взлетает и падает с ошибкой ?) /////////////////////////////////////////// //Подключение к SQL-серверу Попытка Соединение = Новый COMОбъект("ADODB.Connection"); Команда = Новый COMОбъект("ADODB.Command"); Выборка = Новый COMОбъект("ADODB.RecordSet"); Соединение.ConnectionString = "driver={SQL Server};" + "server="+ИмяСервераSQL+";"+ "uid="+ПользовательSQL+";"+ "pwd="+ПарольSQL+";"+ "database="+БазаДанныхSQL+";"; Соединение.ConnectionTimeout = 30; Соединение.CommandTimeout = 600; //Открытие соединение Соединение.Open(); Команда.ActiveConnection = Соединение; Сообщить("Успешное подключение!"); Исключение Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки; Запрос= "SELECT |TimeVal as ДАТАВХОДА, HozOrgan as IDUser, Remark as СЧИТЫВАТЕЛЬ, NAME + FirstName + MidName as ФИО, GETDATE() as ДАТА_ВЫБОРКИ |FROM pLogData, pList |WHERE hozOrgan IN (24, 63, 248, 253, 31, 33, 136, 233, 62, 239, 141, 246, 38, 172, 202, 162, 235, 83, 87, 46, 43) AND |pLogData.hozOrgan = pList.ID AND |TimeVal >= (select CAST('2022-08-03 00:00:05.000' as DATE)) AND |(Remark LIKE '%Вход гл вход, Считыватель 1%' OR Remark LIKE '%Выход гл вход, Считыватель 2%'"); Попытка Команда.CommandText = Запрос; Выборка = Команда.Execute(); Если Выборка.BOF = Ложь Тогда Выборка.MoveFirst(); Пока Выборка.EOF = Ложь Цикл Сообщить("[TimeVal]="+Дата(Выборка.Fields("ДАТАВХОДА").Value) +", [Remark]="+СокрЛП(Выборка.Fields("СЧИТЫВАТЕЛЬ").Value) +", [GETDATE]="+СокрЛП(Выборка.Fields("ДАТА_ВЫБОРКИ").Value) +", [ФИО]="+СокрЛП(Выборка.Fields("ФИО").Value) +", [HozOrgan]="+Дата(Выборка.Fields("IDUser").Value)); Выборка.MoveNext(); КонецЦикла; КонецЕсли; Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; ///////////////////////////////////////// //Закрытия соединения Попытка Соединение.Close(); Сообщить("Соединение закрыто!"); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; | |||
| 1
    
        Gill 03.08.22✎ 13:26 | 
        &НаКлиенте
 Процедура ВыполнитьОбработку(Команда) //Инициализация переменных ИмяСервераSQL = ""; ПользовательSQL = "sa"; ПарольSQL = ""; БазаДанныхSQL = ""; ТаблицаSQL = "pLogData"; ТаблицаSQL2 = "pList"; /////////////////////////////////////////// //Подключение к SQL-серверу Попытка Соединение = Новый COMОбъект("ADODB.Connection"); Команда = Новый COMОбъект("ADODB.Command"); Выборка = Новый COMОбъект("ADODB.RecordSet"); Соединение.ConnectionString = "driver={SQL Server};" + "server="+ИмяСервераSQL+";"+ "uid="+ПользовательSQL+";"+ "pwd="+ПарольSQL+";"+ "database="+БазаДанныхSQL+";"; Соединение.ConnectionTimeout = 30; Соединение.CommandTimeout = 600; //Открытие соединение Соединение.Open(); Команда.ActiveConnection = Соединение; Сообщить("Успешное подключение!"); Исключение Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки; ТекстИнструкции= "SELECT |TimeVal as ДАТАВХОДА, HozOrgan as IDUser, Remark as СЧИТЫВАТЕЛЬ, NAME + FirstName + MidName as ФИО, GETDATE() as ДАТА_ВЫБОРКИ |FROM pLogData, pList |WHERE hozOrgan IN (24, 63, 248, 253, 31, 33, 136, 233, 62, 239, 141, 246, 38, 172, 202, 162, 235, 83, 87, 46, 43) AND |pLogData.hozOrgan = pList.ID AND | TimeVal >= (select CAST('2022-08-03 00:00:05.000' as DATE)) AND |(Remark LIKE '%Вход гл вход, Считыватель 1%' OR Remark LIKE '%Выход гл вход, Считыватель 2%'"); Попытка Команда.CommandText = ТекстИнструкции; Выборка = Команда.Execute(); Если Выборка.BOF = Ложь Тогда Выборка.MoveFirst(); Пока Выборка.EOF = Ложь Цикл Сообщить("[TimeVal]="+Дата(Выборка.Fields("ДАТАВХОДА").Value) +", [Remark]="+СокрЛП(Выборка.Fields("СЧИТЫВАТЕЛЬ").Value) +", [GETDATE]="+СокрЛП(Выборка.Fields("ДАТА_ВЫБОРКИ").Value) +", [ФИО]="+СокрЛП(Выборка.Fields("ФИО").Value) +", [HozOrgan]="+Дата(Выборка.Fields("IDUser").Value)); Выборка.MoveNext(); КонецЦикла; КонецЕсли; Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; ///////////////////////////////////////// //Закрытия соединения Попытка Соединение.Close(); Сообщить("Соединение закрыто!"); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; КонецПроцедуры | |||
| 2
    
        arsik гуру 03.08.22✎ 13:31 | 
        А в менеджере скуля этот запрос работает? И сколько работает? Может по таймауту просто откатывается     | |||
| 3
    
        Gill 03.08.22✎ 13:36 | 
        (2) работает, но долго (около 5 мин, админы утверждают, что это вызвано тем, что HDD на серваке этом)     | |||
| 4
    
        Garykom гуру 03.08.22✎ 13:37 | 
        (0) вам нужен микросервис )) на Go     | |||
| 5
    
        ИУБиПовиц 03.08.22✎ 13:38 | 
        Я в скуле не оч хорошо понимаю. А FROM pLogData, pList их не надо джойнить? AND
 |pLogData.hozOrgan = pList.ID AND Как я понимаю эти таблицы перемножаются, потом условие накладывается? | |||
| 6
    
        arsik гуру 03.08.22✎ 13:41 | 
        (3) Ну блин сделай для начала
 Соединение.ConnectionTimeout = 3000; Соединение.CommandTimeout = 3000; Если все гладко, тогда запрос начинай оптимизировать. Там сразу видно какая то хуерага. | |||
| 7
    
        Ёпрст гуру 03.08.22✎ 14:08 | 
        (0) запрос перепиши по человечьи.. использовать inner join с like + or... ну такое     | |||
| 8
    
        Ёпрст гуру 03.08.22✎ 14:09 | 
        ну и вот это select CAST('2022-08-03 00:00:05.000' as DATE) тоже , полный пэ     | |||
| 9
    
        1Сергей 03.08.22✎ 14:44 | 
        а там реально в скуле поля так называются?     | |||
| 10
    
        kittystark 03.08.22✎ 14:49 | 
        (7) чет не увидел иннерджойна, разве через запятую это он ?
 к (5) даю +1 FROM pLogData, pList - декартово произведение - отсюда и тормоза | |||
| 11
    
        Ёпрст гуру 03.08.22✎ 14:51 | 
        (10) 
 cross join + where на pLogData.hozOrgan = pList.ID это inner join | |||
| 12
    
        arsik гуру 03.08.22✎ 14:54 | 
        Предлагаю подключится через внешний источник данных. Там и запросы можно по человечьи написать.     | |||
| 13
    
        Garykom гуру 03.08.22✎ 14:55 | 
        (12) а админы то на сервере дадут?     | |||
| 14
    
        arsik гуру 03.08.22✎ 15:08 | 
        Через адо дают, а из 1С не дадут?     | |||
| 15
    
        tan76 03.08.22✎ 16:38 | 
        (12) плюсую, этот будет удобно в работе     | |||
| 16
    
        Garykom гуру 03.08.22✎ 16:45 | 
        (14) через адо как ни странно проще чем ВИД     | |||
| 17
    
        Garykom гуру 03.08.22✎ 16:45 | 
        (15) пробовал сам реально это "удобно"?
 причем не на домашнем/локальном компе а на серверах разных? | |||
| 18
    
        arsik гуру 03.08.22✎ 16:59 | 
        (17) На старой работе ФИАС (постгре) через внешний источник подключен. Работает быстро, жрать не просит. Что тебе еще надо?     | |||
| 19
    
        arsik гуру 03.08.22✎ 17:00 | 
        +(18) 150 магазинов (баз) по стране. В центре база ФИАСА.     | |||
| 20
    
        arsik гуру 03.08.22✎ 17:03 | 
        Можно и тяп-ляп на адо сделать. Но кто после будет разбираться? А тут неплохой и удобный слой абстракции который позволят нормальные запросы к внешним данным писать.     | |||
| 21
    
        Garykom гуру 03.08.22✎ 17:15 | 
        (20) мне надо чтобы если схема внешней БД поменялась
 или даже банально она уехала на другой сервер или сменила тип СУБД с MSSQL на PostgreSQL или прочие Oracle, MySQL/MariaDB то можно было легко и просто продолжать юзать без админских прав и конфигуратора | |||
| 22
    
        Garykom гуру 03.08.22✎ 17:16 | 
        И я не за ADO. И не за ВИД.
 Лично мое мнение внешняя прокладка (микросервис) на Go и вызвать его из 1С. | |||
| 23
    
        СеменовСемен 03.08.22✎ 17:18 | 
        (21) если структура поменяется, тотбез конфигуратора не обойтись     | |||
| 24
    
        mikecool 03.08.22✎ 17:19 | 
        (22) а кто будет твой МС править при этих изменениях в источнике?     | |||
| 25
    
        Garykom гуру 03.08.22✎ 17:21 | 
        (23) подразумевал что для задачи типа (0) надо просто
 Тип СУБД Адрес/IP сервера СУБД Логин Пароль Текст SQL запроса И просто вызываем, получая результат в JSON, который о обрабатываем в 1С | |||
| 26
    
        ptiz 03.08.22✎ 17:21 | 
        (3) Долго - из-за кривого запроса, нет нормального соединения (уже написали выше).
 Пример: СтрокаЗапроса = " |SELECT | pLogData.TimeVal, | pLogData.Par4, | pList.Name + ' ' + pList.FirstName + ' ' + pList.MidName |FROM pLogData | LEFT JOIN pList | on pList.ID = pLogData.HozOrgan | WHERE (Par3 = 41) AND (Event = 28) and not pList.Name is null | and pLogData.TimeVal >= " + ДатаСтрокойВSQL(ДатаНачала) + " | and pLogData.TimeVal <= " + ДатаСтрокойВSQL(КонецДня(ДатаОкончания)); | |||
| 27
    
        Garykom гуру 03.08.22✎ 17:21 | 
        (25)+ Пусть схема меняется пофиг, лишь бы запрос выполнялся
 Ну или меняем текст запроса sql | |||
| 28
    
        Garykom гуру 03.08.22✎ 17:22 | 
        (24) микросервис универсальный, его править не надо     | |||
| 29
    
        Garykom гуру 03.08.22✎ 17:23 | 
        (25)+ забыл Порт и ИмяБазы     | |||
| 30
    
        Garykom гуру 03.08.22✎ 17:28 | 
        (28)+ и даже если править
 у меня исходник Go внутри 1С лежит 
И по кнопочке перекомпилится при необходимости в .exe Данный пример чисто под PostgreSQL заточен, но несложно переписать под разные СУБД | |||
| 31
    
        NorthWind 04.08.22✎ 08:00 | 
        (11) по идее, на скорость это не должно влиять. Пишут простые соединения и в where, это проще и короче, и работает по скорости также.     | |||
| 32
    
        NorthWind 04.08.22✎ 08:03 | 
        А запрос тормозит из-за лайков скорее всего.     | |||
| 33
    
        NorthWind 04.08.22✎ 08:04 | 
        Хотя это неточно, нужно смотреть обьем таблиц и что проиндексировано, а что нет     | |||
| 34
    
        Garykom гуру 04.08.22✎ 08:54 | 
        (32) больше там нечему тормозить, только лайки     | |||
| 35
    
        Shur1cIT 04.08.22✎ 09:06 | 
        (0) Как всегда все не читал, почему бы не организовать через внешние источники данных? далее делаешь запрос через обчный конструктор запросов к этим таблицам     | |||
| 36
    
        Gill 05.08.22✎ 10:24 | 
        Господа (и дамы тоже) худо-бедно выборку из SQl получили, теперь продолжение истории:
 Нам в итоге нужно данные из SQL (в частности поле IDUSer как-то синхронизировать с реквизитом в справочнике Сотрудники 1С прикрутив например реквизит такой же ID какой-нибудь) и из РЕГИСТРА СВЕДЕНИЙ "Состояния сотрудников" получить текущее кадровое состояние сотрудника (Работает, В отпуске, на больничном и т.д.). В итоге нужен отчет следующего вида (с отбором по периоду): N Time val IDUser Remark Cотрудник в 1С Кадровое состояние 1 04.08.2022 7:10:06 248 Считыватель 1, Иванов И.И. Работает 2 Петров П.П. В отпуске 3 04.08.2022 7:45:12 200 Считыватель 1, Сидоров И.И. Работает 4 Гринчук П.П. На больничном Что порекомендуете, какие будут мысли? | |||
| 37
    
        Gill 05.08.22✎ 10:26 | 
        (36) 
 Данные сейчас выгружены в соответствующую Табличную часть на форме отчета СКД | |||
| 38
    
        Gill 05.08.22✎ 10:45 | 
        ну как бы вопрос в следующем: как обратится к ТЧ на форме отчета в СКД, далее связать с соответствующим регистром и выгрузить в отчет?     | |||
| 39
    
        ptiz 05.08.22✎ 11:16 | 
        (38) Пихаешь всё в таблицу значений (добавляя туда физ лиц, их кадровые данные) и отдаешь в СКД.     | |||
| 40
    
        Gill 05.08.22✎ 11:20 | 
        (39) можно пример пожалуйста?     | |||
| 41
    
        arsik гуру 05.08.22✎ 11:35 | 
        (40) Давай мы за тебя еще и зарплату будем получать.     | |||
| 42
    
        Gill 05.08.22✎ 11:39 | 
        (41) А как же помощь ближнему ?     | |||
| 43
    
        Ёпрст гуру 05.08.22✎ 11:45 | 
        (36) в своей табличке SQl проапдейть табличку с полем IDUSer, в которую запихаешь iddref справочника пользователи.
 Усё. И доп реквизит не нужон будет | |||
| 44
    
        Garykom гуру 05.08.22✎ 12:01 | 
        (42) Так то ближнему. А ты явно далек от 1С...     | |||
| 45
    
        Gill 05.08.22✎ 12:44 | 
        Так и не нашёл решения. 
 Всем участникам За Советы по существу спасибо, намёки в (41) ,(44) оставлю без комментариев) | |||
| 46
    
        mikecool 05.08.22✎ 12:47 | 
        (28) то бишь все собирается на лету...     | |||
| 47
    
        Garykom гуру 05.08.22✎ 13:21 | 
        (46) все необходимое
 микросервис один раз написал и юзаешь с разными параметрами для разных внешних sql баз запрос sql просто строковый параметр | |||
| 48
    
        Garykom гуру 05.08.22✎ 13:23 | 
        (47)+ минус ado что оно под линуксом не пашет как и на фреше
 тут же плюс что поднял микросервис и даже из фреша можно обращаться | 
 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |