|
Выборка данных из 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 что оно под линуксом не пашет как и на фреше
тут же плюс что поднял микросервис и даже из фреша можно обращаться |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |