Имя: Пароль:
1C
1C 7.7
v7: Зависает отчет (оперучет, SQL, 1с++)
,
0 Stella0608
 
21.02.13
13:55
Собственно, проблема такая.
Есть отчет, переписанный на SQL через 1с++.
Через какое-то время (только в этом отчете) обнаружилась одна проблема.
Описываю: когда указываешь дополнительную группировку и нажимаешь "сформировать", отчет формируется без проблем. Но если еще раз нажать "сформировать", 1с зависает, помогают только 3 кнопки.
Наличие этой группировки добавляет еще одно внутреннее соединение в запрос.
Т.е. пример: у нас есть реквизит Город типа Справочник, у этого города есть реквизит Регион типа справочник Регионы, вот только если выбрать дополнительно регион, проявляется проблема. При этом в запросе появляется строчка кода, добавляющая соединение справочника Города со справочником Регионы.
Отладка показала следующую вещь. Сам запрос выполняется сколько угодно раз, и результаты запроса без проблем выгружаются в ТЗ.
Но: если выполнять запрос больше одного раза, после собственно выполнения запроса, отчет зависает практически на любой строчке кода в 1с.
К примеру, отчет может подвесить строчка Таб = СоздатьОбъект("Таблица").
Может проблема известная и уже знает как с ней бороться.
Ах да, конфа нетиповая, 27 релиз, SQL 2000.
1 SMakcik
 
21.02.13
13:57
А остальное самим нужно додумать?
2 SMakcik
 
21.02.13
13:57
где-то неправильно. Такой ответ пойдеть )))
3 Stella0608
 
21.02.13
13:58
(1) Наводящие вопросы принимаются :).
4 viktor_vv
 
21.02.13
13:59
Скорее всего текст запроса формируется динамически, и при повторном запуске неправильно формируется тест.
Или со временными таблицами.
Ну так, потелепатировать.
5 ДенисЧ
 
21.02.13
13:59
(3) Наводящий вопрос: сколько вы не доплатили человеку, который рисовал этот отчёт? :-))
6 viktor_vv
 
21.02.13
13:59
(3) Можно текст запроса вывалить, надеюсь он не на три страницы.
7 МихаилМ
 
21.02.13
14:01
все просто: не объявляются локальные переменные.
при совпадении имени переменной например текста запроса
может получиться мегазапрос.
8 Stella0608
 
21.02.13
14:01
Отчет рисовала я :).
Вот строчка кода, на которой валится отчет:
   Если СоедГород = 1 Тогда  
       //если фильтр идет по группе, берем внутреннее соединение, иначе левое
       Текст = Текст + ?(ВыбРегион.Выбран() = 1,"INNER","LEFT") +" JOIN SC5677 СпрГор ON СпрКл.SP5699 = СпрГор.ID
       |";
   КонецЕсли;  
Переменная СоедГород в данном случае равна 1.
9 SMakcik
 
21.02.13
14:02
(7) ну это так потелипатировать )))
10 viktor_vv
 
21.02.13
14:03
Лучше покажи, после этого

Сообщить(Текст);
11 Stella0608
 
21.02.13
14:04
При повторном формировании отчета делаю Сообщить("Текст").
Текст запроса остается преждним.
ТЗ с данными, которая выдается на экран после выполнения запроса, вроде как тоже похожа на правильную. Но построчного сравнения не делала.
Базы, к сожалению, нет под рукой. Могу глянуть чуть позже.
Вопрос поступил от пользователя. Отчет под рукой есть.
12 Stella0608
 
21.02.13
14:06
(9) Мне, к сожалению, самой приходится телепатировать. :)
Пока известно, что отчет валится после дополнительного соединения.
13 viktor_vv
 
21.02.13
14:07
(11) Странно, как фото в купальнике в личке (тут все хорошо и правильно) так пожалуйста, как тест запроса, так прям тайны мадридского двора :).
14 Попытка1С
 
21.02.13
14:09
(8) Вы про мегапарсер вообще в курсе?
15 Stella0608
 
21.02.13
14:09
(13) Пытаюсь получить. Пользователь скажем так, не сидит рядом со мной :).
К тому же, страшно услышать в ответ что я нуб без комментариев :))).
16 Stella0608
 
21.02.13
14:10
(14) В курсе. :)
17 isarzh
 
21.02.13
14:11
(1) Попробуй простой текст запроса выполни дважды.
18 МихаилМ
 
21.02.13
14:12
(8)
если запрос к ms sql, то хорошо явно указывать подсказки блокировок.

т.к. возможно блокировки при первом выполненни
блокируют выполнение при повторном.
19 Ёпрст
 
21.02.13
14:23
(0) прибить cfg  и mlg , для начала
20 Ёпрст
 
21.02.13
14:23
да, и хинты нолок в текст запроса
21 toypaul
 
гуру
21.02.13
14:25
(0) обновление статистик обычно помогает. оптимзатору иногда крышу сносить при усложнении запросов, если статистка старая. ну или (18), но это уже сложнее. обычно помогает более простой способ. мне уже не раз помогало = в том числе при больших объемах данных.
22 toypaul
 
гуру
21.02.13
14:28
ой. как обычно не дочитал до конца :). чтобы зависал после определ. кол-ва выполнений, это не статистика. тем более на произвольной строчке кода = это вообще хрень какая-то.
23 Попытка1С
 
21.02.13
14:43
(22) "это вообще хрень какая-то."

хорошо подитожил)
24 varelchik
 
21.02.13
15:35
Тебеж попросили.
Ответь на (10)
25 Stella0608
 
21.02.13
15:47
В общем так. Базы нет под рукой, и не могу воспроизвести текст запроса на рабочей базе с нужными фильтрами :(.
В целом - что-то подобное:

SELECT  
СпрТов.SP3500 [Производитель $Справочник.Производитель], SUM(Kol1) Kol1, SUM(Seb1) Seb1, SUM(ST1) ST1,  
GROUPING (СпрТов.SP3500) as Группа1 FROM              
(SELECT SP6886, SP6888,
SUM(Kol1) Kol1, SUM(Seb1) Seb1, SUM(ST1) ST1
FROM
(SELECT SP6886, SP6888,
CASE WHEN DATE_TIME_IDDOC BETWEEN :НачДата1 AND :КонДата1~ THEN SP6889 ELSE 0 END Kol1,
CASE WHEN DATE_TIME_IDDOC BETWEEN :НачДата1 AND :КонДата1~ THEN SP6890 ELSE 0 END ST1,
CASE WHEN DATE_TIME_IDDOC BETWEEN :НачДата1 AND :КонДата1~ THEN SP6891 ELSE 0 END Seb1,
IDDOC
FROM $Регистр.УчетПродажОб AS РегПрод
WHERE (РегПрод.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата~)) AS MainTab
GROUP BY SP6886, SP6888) AS MainTab2
INNER JOIN SC33 СпрТов ON MainTab2.SP6886 = СпрТов.ID
INNER JOIN SC46 СпрКл ON MainTab2.SP6888 = СпрКл.ID
INNER JOIN SC5677 СпрГор ON СпрКл.SP5699 = СпрГор.ID
WHERE (СпрКл.SP5699  = :ВыбГород) AND (СпрГор.SP5708  = :ВыбРегион) GROUP BY СпрТов.SP3500 WITH ROLLUP

Глюк происходит, когда в запросе присутствует эта строчка:
INNER JOIN SC5677 СпрГор ON СпрКл.SP5699 = СпрГор.ID
26 Ёпрст
 
21.02.13
15:49
(25) хинты (nolock) понавтыкай , для начала
27 Mikeware
 
21.02.13
15:49
(25) у вас што, про метапарсер не слышали?
28 Stella0608
 
21.02.13
15:51
(27) Запросу сто лет и писался на чистом скуле (когда практически вообще его не знала :)), ну а сейчас переделывать все на метапарсер желания нет :).
29 Stella0608
 
21.02.13
15:52
(26) Попробую.
30 Ёпрст
 
21.02.13
15:52
SP5699 какой тип имеет ? в справочнике ?
31 Ёпрст
 
21.02.13
15:53
это реквизит какого типа ?
32 Ёпрст
 
21.02.13
15:53
ЗЫ: <справочник>, без вида поди, да ?
33 viktor_vv
 
21.02.13
15:57
Смущает вот эти ступенчатые инеры

INNER JOIN SC46 СпрКл ON MainTab2.SP6888 = СпрКл.ID
INNER JOIN SC5677 СпрГор ON СпрКл.SP5699 = СпрГор.ID

Помнится у меня что-то подобное тормознее было, чем left с условием IS NOT NULL.
34 Stella0608
 
21.02.13
15:58
SP5699 - реквизит справочника Контрагенты. Называется Город. Тип - Справочник.Города.
35 viktor_vv
 
21.02.13
16:00
А если по этому условию попадает Left как работает запрос ?

   Если СоедГород = 1 Тогда  
       //если фильтр идет по группе, берем внутреннее соединение, иначе левое

       Текст = Текст + ?(ВыбРегион.Выбран() = 1,"INNER","LEFT") +" JOIN SC5677 СпрГор ON СпрКл.SP5699 = СпрГор.ID
       |";
   КонецЕсли;
36 Stella0608
 
21.02.13
16:00
Если что, база объемом где-то 5 гиг, т.е. небольшая.
37 leshikkam
 
21.02.13
16:01
Поставьте признак Сортировка (36) на реквизит Город в справочнике Контрагенты (создайте индекс)
38 Stella0608
 
21.02.13
16:08
(35) Полной уверенности нет, но есть подозрение, что это не выполняется вообще никогда. Т.е. задумка была, но не реализована.
Т.к. выше встречается вот такой код:
   Если ВыбРегион.Выбран() = 1 Тогда
       СоедКл = 1;
       СоедГород = 1;
   КонецЕсли;
39 Stella0608
 
21.02.13
16:09
Все ответы, которые прямо сейчас попробовать возможности нет, обязательно приму к сведению!
40 Mikeware
 
21.02.13
16:39
(28) так если заменить названия на человечьи - скорее всего, и ошибку проще увидеть будет
41 Stella0608
 
21.02.13
17:44
(40) Я бы не сказала, т.к. уже день ковыряю отчет с нормальными "человеческими" именами :).
42 Злой Бобр
 
21.02.13
23:31
(40) Непоможет. Не в данном случае.
(0) Или текст в студию, или лучше сохранить отчет как внешний и положить на файлопомойку. Ну так проще будет, а то угадайка неработает я так понял.
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.