Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Прямой запрос. 1С не может обработать большой результат запроса. (число прочтений - 5059 )
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 записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #15 - 04. Октября 2010 :: 07:19
Печать  
А нафига inner join справочника Сотрудники ?

ЗЫ: вот так работает ?

Код
Выбрать все
ЗапросКЖурналуЗарплата = СоздатьОбъект("ODBCRecordset");
ТекстЗапросаДляЖЗ = "
	|SELECT
	|  ЖР.FF202 AS [ОсновнойЭлемент $Справочник.Сотрудники]
	|FROM
	|  $ЖурналРасчетов.Зарплата AS ЖР (nolock)
	|";
		ЗапросКЖурналуЗарплата.Открыть(ТекстЗапросаДляЖЗ);
ЗапросКЖурналуЗарплата.Вначало();
Пока ЗапросКЖурналуЗарплата.Конец() = 0 Цикл
  Сообщить(ЗапросКЖурналуЗарплата.ПолучитьЗначение("ОсновнойЭлемент "));
 ЗапросКЖурналуЗарплата.След();
КонецЦикла; 


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


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #16 - 04. Октября 2010 :: 07:25
Печать  
Таже самая ошибка Печаль
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



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


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #18 - 04. Октября 2010 :: 07:30
Печать  
3.2.2.0
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #19 - 04. Октября 2010 :: 07:32
Печать  
почитай в гугле про
"Подключение занято до получения результатов для другого hstmt"
там есть ответ.
Например, тут
http://www.forum.mista.ru/topic.php?id=489058
  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #20 - 04. Октября 2010 :: 07:50
Печать  
Перезапустил sql
Теперь пишет
"Колонка с именем (ОсновнойЭлемент) отсутствует в выборке"
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #21 - 04. Октября 2010 :: 08:28
Печать  
ajax писал(а) 04. Октября 2010 :: 06:28:
Выдает ошибку
"Подключение занято до получения результатов для другого hstmt"


ЗапросКЖурналуЗарплата.Открыть(ТекстЗапроса, 1);

не?
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
KonstSV
Junior Member
**
Отсутствует



Сообщений: 39
Местоположение: Москва
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #22 - 04. Октября 2010 :: 08:42
Печать  
К решению этой проблемы необходимо подойти с другой стороны.

НЕ ДОЛЖНО быть такого, чтобы SQL-ный запрос возвращал такое большое количество строк.

Надо либо разбивать этот запрос на несколько, либо на сервере выполнять основные вычисления
и возвращать уже практически готовые данные.
  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #23 - 04. Октября 2010 :: 08:46
Печать  
Неа, так выдает эту ошибку.
До этого сообщение об ошибке вылечилось перезапуском SQL сервера
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #24 - 04. Октября 2010 :: 08:49
Печать  
KonstSV писал(а) 04. Октября 2010 :: 08:42:
К решению этой проблемы необходимо подойти с другой стороны.

НЕ ДОЛЖНО быть такого, чтобы SQL-ный запрос возвращал такое большое количество строк.

Надо либо разбивать этот запрос на несколько, либо на сервере выполнять основные вычисления
и возвращать уже практически готовые данные.

так это уже было сказано в #8
  
Наверх
 
IP записан
 
ajax
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 27
Зарегистрирован: 28. Ноября 2008
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #25 - 04. Октября 2010 :: 08:58
Печать  
Согласен, но все же как работать с открытой выборкой?
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #26 - 04. Октября 2010 :: 09:01
Печать  
ajax писал(а) 04. Октября 2010 :: 08:58:
Согласен, но все же как работать с открытой выборкой?


А чего, как в #15 не работает ?
Попробуй не явно указывать имена полей:
Сообщить(ЗапросКЖурналуЗарплата.ПолучитьЗначение(1));

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



Сообщений: 39
Местоположение: Москва
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Прямой запрос. 1С не может обработать большой результат запроса.
Ответ #27 - 04. Октября 2010 :: 10:01
Печать  
Цитата:
так это уже было сказано в #8


Конечно, Z1, вы говорили о том же, но как показало дальнейшее обсуждение, ваши слова услышаны не были.
Поэтому и появилась моя реплика.

Конечно, можно освоить предложенный в #7 способ обхода выборки и это будет, в любом случае, полезный опыт.

Но хочется ещё раз подчеркнуть, что правильный путь решения этой проблемы - "копать" в сторону уменьшения
размера выборки, получаемой с SQL-сервера.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать