Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Очень популярная тема (более 25 ответов) Прямой запрос. 1С не может обработать большой результат запроса. (число прочтений - 5065 )
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Прямой запрос. 1С не может обработать большой результат запроса.
01. Октября 2010 :: 10:55
Печать  
Переделываю расчет НДФЛ в ЗиК-е на прямой запрос. При выполнении запроса происходит лавинообразное "съедание" памяти и затем падение 1С. Как быть?
Вот код:
[code]Мета = СоздатьОбъект("MetaDataWork");
     СЗначисления = СоздатьОбъект("СписокЗначений");

     Для Индекс = 1 По ГруппаРасчетов.ВсеУдержанныеНДФЛ.Количество() Цикл
           еУдержанныеНДФЛ.ПолучитьРасчет(Индекс)), 27, 13)));
     КонецЦикла;
     СтрокаУсловияВсеУдержанныеНДФЛ = Мета.ПолучитьСтрокуИзСЗ(СЗначисления);
     СЗначисления.УдалитьВсе();
     
     Для Индекс = 1 По ГруппаРасчетов.ВсеИсчисленныеНДФЛ.Количество() Цикл
           еИсчисленныеНДФЛ.ПолучитьРасчет(Индекс)), 27, 13)));
     КонецЦикла;
     СтрокаУсловияВсеИсчисленныеНДФЛ = Мета.ПолучитьСтрокуИзСЗ(СЗначисления);
     СЗначисления.УдалитьВсе();
     
     Для Индекс = 1 По ГруппаРасчетов.ОсобоеИсчислениеНДФЛ.Количество() Цикл
           обоеИсчислениеНДФЛ.ПолучитьРасчет(Индекс)), 27, 13)));
     КонецЦикла;
     СтрокаУсловияОсобоеИсчислениеНДФЛ = Мета.ПолучитьСтрокуИзСЗ(СЗначисления);
     СЗначисления.УдалитьВсе();
     
     ЗапросКЖурналуЗарплата = СоздатьОбъект("ODBCRecordset");
     
     ТекстЗапросаДляЖЗ = "
     |SELECT
     |  ЖР.iddoc AS [Документ $Документ],
     |  j_doc.iddocdef AS Документ_вид,
     |  СпрСотрудников.CODE AS [КодСотрудника],
     |  СпрСотрудников.DESCR AS [НаименованиеСотрудника],
     |  ЖР.FF202 AS [ОсновнойЭлемент $Справочник.Сотрудники],
     //|  $СпрСотрудников.ОсновнойЭлемент AS [ОсновнойЭлемент $Справочник.Сотрудники],
     |  ЖР.idalg AS [ВР $ВидРасчета],
     |  ЖР.period AS ПериодРегистрации,
     |  ЖР.dateb AS НачалоПериодаДействия,
     |  ЖР.datee  AS ОкончаниеПериодаДействия,
     |  ЖР.SP1089 AS НомерСтрокиДокумента,
     |  ЖР.Recalc,
     |  CASE
     |            WHEN ЖР.IDALG IN (" + СтрокаУсловияВсеУдержанныеНДФЛ + ") THEN 1
     |            ELSE 0
     |  END AS ВходитВВсеУдержанныеНДФЛ,
     |  CASE
     |            WHEN ЖР.IDALG IN (" + СтрокаУсловияВсеИсчисленныеНДФЛ + ") THEN 1
     |            ELSE 0
     |  END AS ВходитВВсеИсчисленныеНДФЛ,
     |  CASE
     |            WHEN ЖР.IDALG IN (" + СтрокаУсловияОсобоеИсчислениеНДФЛ + ") THEN 1
     |            ELSE 0
     |  END AS ВходитВОсобоеИсчислениеНДФЛ,
     |  SUM (ЖР.result) AS Результат,
     |  $ПоследнееЗначение.Сотрудники.СтатусНеРезидента(ЖР.FF202, :КонГода) AS [СтатусНеРезидента]
     |FROM
     |  $ЖурналРасчетов.Зарплата AS ЖР (nolock)
     |INNER JOIN
     |  _1sjourn j_doc (nolock) on j_doc.iddoc = ЖР.iddoc
     |INNER Join
     |  $Справочник.Сотрудники As СпрСотрудников (nolock) ON СпрСотрудников.ID = ЖР.FF202
     |WHERE
     |  (ЖР.FF202 IN (Select Val FROM #Сотрудники)) AND
     |  (ЖР.Result <> 0) AND
     |  ((ЖР.period >= '" + Формат(НачМесяца(НачалоПеродаОсмотра),"Д ГГГГММДД") + "M') AND (ЖР.period <= '" + Формат(НачМесяца(ОкончаниеПеродаОсмотра),"Д ГГГГММДД") + "M'))
     |GROUP BY дников.DESCR,ЖР.dateb,ЖР.datee,ЖР.SP1089,ЖР.RECALC
     |ORDER BY СпрСотрудников.CODE
     |";
     ЗапросКЖурналуЗарплата.УложитьСписокОбъектов(Сотрудники,"#Сотрудники");
     ЗапросКЖурналуЗарплата.УстановитьТекстовыйПараметр("КонГода",ОкончаниеГода);
     Предупреждение("Запускаем прямой запрос");
     ТЗ = СоздатьОбъект("ИндексированнаяТаблица");
     ТЗ = ЗапросКЖурналуЗарплата.ВыполнитьИнструкцию(ТекстЗапросаДляЖЗ);
     Предупреждение("Запрос выполнился");[/code]
  
Наверх
 
IP записан
 
leshik
1c++ donor
Отсутствует



Сообщений: 820
Местоположение: Пятигорск
Зарегистрирован: 22. Апреля 2007
Пол: Мужской
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #1 - 01. Октября 2010 :: 11:03
Печать  
А так?
Код
Выбрать все
ЗапросКЖурналуЗарплата.ВыполнитьИнструкцию(ТекстЗапросаДляЖЗ,ТЗ); 

  
Наверх
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #2 - 01. Октября 2010 :: 11:13
Печать  
В профайлере подсмотрел текст запроса, запустил его QA, отработал нормально, вернул ~ 1,1 млн. строк.

  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #3 - 01. Октября 2010 :: 11:22
Печать  
попробуй без индексированной таблицы

ТЗ1 = ЗапросКЖурналуЗарплата.ВыполнитьИнструкцию(ТекстЗапросаДляЖЗ);


скорее всего таблица значений не справляется с такими объемами.
для проверки оставь в спискесотрудников двух сотрудников.
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #4 - 01. Октября 2010 :: 11:25
Печать  
ajax писал(а) 01. Октября 2010 :: 11:13:
В профайлере подсмотрел текст запроса, запустил его QA, отработал нормально, вернул ~ 1,1 млн. строк.



памяти не хватает, для создания ТЗ такого объема.. вот и падает.
  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #5 - 01. Октября 2010 :: 11:29
Печать  
leshik писал(а) 01. Октября 2010 :: 11:03:
А так?
Код
Выбрать все
ЗапросКЖурналуЗарплата.ВыполнитьИнструкцию(ТекстЗапросаДляЖЗ,ТЗ); 



Теперь выдало такую ошибку
Код
Выбрать все
 Error! Cannot allocate memory block 

  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #6 - 01. Октября 2010 :: 11:30
Печать  
Z1 писал(а) 01. Октября 2010 :: 11:22:
попробуй без индексированной таблицы

ТЗ1 = ЗапросКЖурналуЗарплата.ВыполнитьИнструкцию(ТекстЗапросаДляЖЗ);


скорее всего таблица значений не справляется с такими объемами.
для проверки оставь в спискесотрудников двух сотрудников.


На меньшем количестве отрабатывает нормально.
Предлагаете разбить список сотрудников на несколько частей и обрабатывать их отдельно?
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #7 - 01. Октября 2010 :: 11:31
Печать  
попробуй просто через Открыть() + вНачало() + цикл пока Конец() =1 + След().. т.е обходом обойти выборку запроса.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #8 - 01. Октября 2010 :: 11:34
Печать  
ajax писал(а) 01. Октября 2010 :: 11:30:
Z1 писал(а) 01. Октября 2010 :: 11:22:
попробуй без индексированной таблицы

ТЗ1 = ЗапросКЖурналуЗарплата.ВыполнитьИнструкцию(ТекстЗапросаДляЖЗ);


скорее всего таблица значений не справляется с такими объемами.
для проверки оставь в спискесотрудников двух сотрудников.


На меньшем количестве отрабатывает нормально.
Предлагаете разбить список сотрудников на несколько частей и обрабатывать их отдельно?

ну конечно.обрабатывать их отдельно. ну получиться у тебя в отчет вывалить миллион строк. Что дальше ?

ну а если это как бы промежуточная обработка и дальше ты что-то делаешь на 1с и получаешь небольшие выборки
то переписывай этот код на t-sql

  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #9 - 01. Октября 2010 :: 11:51
Печать  
Eprst писал(а) 01. Октября 2010 :: 11:31:
попробуй просто через Открыть() + вНачало() + цикл пока Конец() =1 + След().. т.е обходом обойти выборку запроса.


А можно какой нибудь небольшой пример, просто "Открыть()" я никогда не пользовался
  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #10 - 04. Октября 2010 :: 06:01
Печать  
Как обратиться к результатам открытой выборки?
Делаю так
Код
Выбрать все
ЗапросКЖурналуЗарплата = СоздатьОбъект("ODBCRecordset");
........
Текст запроса
........
ЗапросКЖурналуЗарплата.Вначало();
Пока ЗапросКЖурналуЗарплата.Конец() = 0 Цикл
Сотрудник = ЗапросКЖурналуЗарплата.ОсновнойЭлемент;
КонецЦикла; 



Выдает ошибку.
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #11 - 04. Октября 2010 :: 06:21
Печать  
Код
Выбрать все
ЗапросКЖурналуЗарплата.Открыть(ТекстЗапроса);
ЗапросКЖурналуЗарплата.ВНачало();
Пока ЗапросКЖурналуЗарплата.Конец()=0 Цикл
	Сообщить(ЗапросКЖурналуЗарплата.ПолучитьЗначение(1));
	ЗапросКЖурналуЗарплата.След();
КонецЦикла; 

  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #12 - 04. Октября 2010 :: 06:28
Печать  
Выдает ошибку
"Подключение занято до получения результатов для другого hstmt"
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #13 - 04. Октября 2010 :: 06:51
Печать  
весь код.. кажи.
  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #14 - 04. Октября 2010 :: 07:07
Печать  
Код
Выбрать все
ЗапросКЖурналуЗарплата = СоздатьОбъект("ODBCRecordset");

	ТекстЗапросаДляЖЗ = "
	|SELECT
	|  ЖР.iddoc AS [Документ $Документ],
	|  j_doc.iddocdef AS Документ_вид,
	|  СпрСотрудников.CODE AS [КодСотрудника],
	|  СпрСотрудников.DESCR AS [НаименованиеСотрудника],
	|  ЖР.FF202 AS [ОсновнойЭлемент $Справочник.Сотрудники],
	//|  $СпрСотрудников.ОсновнойЭлемент AS [ОсновнойЭлемент $Справочник.Сотрудники],
	|  ЖР.idalg AS [ВР $ВидРасчета],
	|  ЖР.period AS ПериодРегистрации,
	|  ЖР.dateb AS НачалоПериодаДействия,
	|  ЖР.datee  AS ОкончаниеПериодаДействия,
	|  ЖР.SP1089 AS НомерСтрокиДокумента,
	|  ЖР.Recalc,
	|  CASE
	|		WHEN ЖР.IDALG IN (" + СтрокаУсловияВсеУдержанныеНДФЛ + ") THEN 1
	|		ELSE 0
	|  END AS ВходитВВсеУдержанныеНДФЛ,
	|  CASE
	|		WHEN ЖР.IDALG IN (" + СтрокаУсловияВсеИсчисленныеНДФЛ + ") THEN 1
	|		ELSE 0
	|  END AS ВходитВВсеИсчисленныеНДФЛ,
	|  CASE
	|		WHEN ЖР.IDALG IN (" + СтрокаУсловияОсобоеИсчислениеНДФЛ + ") THEN 1
	|		ELSE 0
	|  END AS ВходитВОсобоеИсчислениеНДФЛ,
	|  SUM (ЖР.result) AS Результат,
	|  $ПоследнееЗначение.Сотрудники.СтатусНеРезидента(ЖР.FF202, :КонГода) AS [СтатусНеРезидента]
	|FROM
	|  $ЖурналРасчетов.Зарплата AS ЖР (nolock)
	|INNER JOIN
	|  _1sjourn j_doc (nolock) on j_doc.iddoc = ЖР.iddoc
	|INNER Join
	|  $Справочник.Сотрудники As СпрСотрудников (nolock) ON СпрСотрудников.ID = ЖР.FF202
	|WHERE
	|  (ЖР.FF202 IN (Select Val FROM #Сотрудники)) AND
	|  (ЖР.Result <> 0) AND
	|  ((ЖР.period >= '" + Формат(НачМесяца(НачалоПеродаОсмотра),"Д ГГГГММДД") + "M') AND (ЖР.period <= '" + Формат(НачМесяца(ОкончаниеПеродаОсмотра),"Д ГГГГММДД") + "M'))
	|GROUP BY дников.DESCR,ЖР.dateb,ЖР.datee,ЖР.SP1089,ЖР.RECALC
	|ORDER BY СпрСотрудников.CODE
	|";
	ЗапросКЖурналуЗарплата.УложитьСписокОбъектов(Сотрудники,"#Сотрудники");
	ЗапросКЖурналуЗарплата.УстановитьТекстовыйПараметр("КонГода",ОкончаниеГода);
	ЗапросКЖурналуЗарплата.Открыть(ТекстЗапросаДляЖЗ);
ЗапросКЖурналуЗарплата.Вначало();
Пока ЗапросКЖурналуЗарплата.Конец() = 0 Цикл
Сотрудник = ЗапросКЖурналуЗарплата.ПолучитьЗначение(5); 

  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать