| 
    
            
         
         | 
    
    
  | 
v7: Ошибка при выполнении прямого запроса | ☑ | ||
|---|---|---|---|---|
| 
    0
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    13:20 
 | 
         
        Выполняю подобный запрос 
 
        SELECT Sum(Остаток), Sum(Резерв) FROM ( SELECT Sum(Рег1.КоличествоОстаток) Остаток, (Null) Резерв FROM $РегистрОстатки.ОстаткиТМЦ(,, (Номенклатура = :ВыбНом),,) AS Рег1 UNION ALL SELECT (Null) Остаток, Sum(Рег2.КоличествоОстаток) Резерв FROM $РегистрОстатки.РезервыТМЦ(,, (Номенклатура = :ВыбНом),,) AS Рег2) AS Подзапрос Выполняю скалярный (получаю резерв и остаток), после первого выполнения пишет ошибку "Подключение занято до получения другого hstmt" интересует причина данной ошибки до этого запроса выполняю 2 запроса (приведенный выше только отдельно остаток и резерв)  | 
|||
| 
    1
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    13:34 
 | 
         
        Выяснил что ошибка возникает при выполнении следующего запроса после этого
 
        текст запроса с ошибкой SELECT Sum(Рег.КоличествоОстаток) Остаток, (Null) Резерв FROM $РегистрОстатки.ОстаткиТМЦ(,, (Номенклатура = :ВыбНом) AND (Склад = :ВыбСклад),,) AS Рег если убрать запрос (0) то все выполняется нормально..  | 
|||
| 
    2
    
        Mikeware    
     08.10.13 
            ✎
    13:37 
 | 
||||
| 
    3
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    13:41 
 | 
         
        писал
 
        SET NOCOUNT ON может проблема в Рез = рс10.ВыполнитьСкалярный(); Сообщить(Рез.Остаток); Сообщить(Рез.Резерв); Рез = ""; ? или как закрыть курсор?  | 
|||
| 
    4
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    14:19 
 | 
        
и если убрать тестовый код то все норм...  | 
|||
| 
    5
    
        Mikeware    
     08.10.13 
            ✎
    14:24 
 | 
         
        жуть. анахрена?     
         | 
|||
| 
    6
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    14:27 
 | 
         
        модуль проведения заявки покупателя, у меня итоговый результат 4-10 раз ускорение проведения документа на моей машине, на сервере (где sql сервер отдельно стоит) почти не дает результата около 40% прирост... поэтому пытаюсь уменьшить количество обращений к серверу...     
         | 
|||
| 
    7
    
        mikecool    
     08.10.13 
            ✎
    14:28 
 | 
         
        объединить в один запрос религия не позволила?
 
        и писать (null) вместо 0 для числовых полей - я бы по рукам надавал  | 
|||
| 
    8
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    14:29 
 | 
         
        (7) я исправил уже... объединить в в один где именно?     
         | 
|||
| 
    9
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    14:29 
 | 
         
        исправление в (4)     
         | 
|||
| 
    10
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    14:33 
 | 
         
        (7) просто примеры выше нереальные были писал как бы для примера, в (4) реальный код...     
         | 
|||
| 
    11
    
        Salimbek    
     08.10.13 
            ✎
    14:36 
 | 
         
        (9) У тебя первым выполняется ЗапросТекст, туда и вставь "SET NOCOUNT ON" Или вообще, самой первой строкой "рс.выполнитьскалярный("SET NOCOUNT ON")"... Хотя... Вот зачем тебе так много "рс4, рс6, рс10"? И возможно в одном РекордСете ты отключаешь вывод количества обработанных строк, а в другом каком-то остается включенным и продолжает падать.     
         | 
|||
| 
    12
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    14:42 
 | 
         
        (11) добавил во все запросы "SET NOCOUNT ON", не помогло :( 
 
        а много для того чтобы получить все нужные данные 
и все запросы с параметрами и выполняются скалярно, кроме первых трех, они возвращают таблицы и только 1 раз  | 
|||
| 
    13
    
        ADirks    
     08.10.13 
            ✎
    14:44 
 | 
         
        (12) подсказываю 
 
        Warning: Null value is eliminated by an aggregate or other SET operation  | 
|||
| 
    14
    
        ADirks    
     08.10.13 
            ✎
    14:44 
 | 
         
        ... в студии свой запрос выполни, прежде чем репу чесать     
         | 
|||
| 
    15
    
        mikecool    
     08.10.13 
            ✎
    14:47 
 | 
         
        (8) написать типа
 
        селект фром (свернутая табличная часть документа) левое соединение остатки по номенклатура, склад из шапки и т.п. левое соединение резервы по номенклатура, склад из шапки и т.п. остальное если надо  | 
|||
| 
    16
    
        mikecool    
     08.10.13 
            ✎
    14:47 
 | 
         
        (12) афигеть     
         | 
|||
| 
    17
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    14:52 
 | 
         
        (12) ну да, дело в том что не всегда нужно использовать все данные... совместно используются только остатки и резервы...
 
        одни запросы на случай корректировки заказа, другие на случай заказа на поставку, одни на случай неподтвержденной заявки, один на случай резерва, я не знаю будет ли оптимально вернуть все в одной талице когда это не надо для обработки проведения  | 
|||
| 
    18
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    15:02 
 | 
         
        (13) на запросе в (4) не пишет предупреждений, там я null не использую, и нет никаких сообщений...
 
        ошибка так и остается :(  | 
|||
| 
    19
    
        Salimbek    
     08.10.13 
            ✎
    15:10 
 | 
         
        (17) Я не знаю, как поведут себя разные РекордСеты, т.к. 1. подключены они к одной базе, 2. 1С-ка выполняет запросы все равно по порядку, смысла в том, чтобы прыгать от одного рекордсета к другому я по этому не вижу. 3. Есть шанс, что 
 
        Я бы сделал тупенько, один РС, и далее по порядку - надо такие-то данные - запрос сделал, выполнил, обработал. Надо еще что-то, следующий запрос, и т.д. Ну и последнее, как правильно озвучил (15) - какой смысл раскидывать куче маленьких запросов, если можно одним запросом вытащить все данные для работы в ТЗ, а потом уже спокойно перебирать, не бегая к БД за каждым чихом.  | 
|||
| 
    20
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    15:15 
 | 
         
        (19) с рс4 по рс 7 я и собирался в 1 запрос собрать     
         | 
|||
| 
    21
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    15:18 
 | 
         
        что будет быстрее списк номенклатуры Left Join с регистрами  или в каждом регистре select val from #СписокНом?     
         | 
|||
| 
    22
    
        trad    
     08.10.13 
            ✎
    15:23 
 | 
         
        Ставлю на то, что из-за null или еще чего то, прет warning, который 1с++ный рекордсет не выгребает (так устроен этот рекордсет) из буфера. Следовательно обращения к базе недопустимы пока буфер занят.
 
        Нужно либо избавится от варнинга, либо ODBCRecordSet::Закрыть(), но тогда, вроде, prepare отвалится.  | 
|||
| 
    23
    
        trad    
     08.10.13 
            ✎
    15:24 
 | 
         
        * из-за null в агрегатной функции     
         | 
|||
| 
    24
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:08 
 | 
         
        Так же будет лучше всего?
 
        
     | 
|||
| 
    25
    
        trad    
     08.10.13 
            ✎
    16:21 
 | 
         
        Если в ИБ практикуется массовое перепроведение документов, то
 
        УложитьСписокОбъектов(СписокНоменклатуры, "#СписНом") при проведение лучше не пользоваться. Чревато http://support.microsoft.com/?scid=kb;en-us;891553&spid=2852  | 
|||
| 
    26
    
        trad    
     08.10.13 
            ✎
    16:21 
 | 
         
        + равно как и любыми фильтрами на основе tempdb     
         | 
|||
| 
    27
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:22 
 | 
         
        Тогда так?
 
        
     | 
|||
| 
    28
    
        mikecool    
     08.10.13 
            ✎
    16:23 
 | 
         
        табличную часть дока закинуть во времянку и юзать ее далее
 
        можно даже пробовать одним пакетом это выполнить  | 
|||
| 
    29
    
        mikecool    
     08.10.13 
            ✎
    16:24 
 | 
         
        +28 если будут лефт джойны вирт. таблиц - то им в обязаловку устраивать ограничения на номенклатуру и склады     
         | 
|||
| 
    30
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:25 
 | 
         
        такой массив не пойдет? ('     U   ','     V   ','     6   ','     K   ','     N   ','     R   ','     S   ','     T   ','     O   ','     L   ','     I   ','     H   ','     M   ','     P   ')     
         | 
|||
| 
    31
    
        trad    
     08.10.13 
            ✎
    16:27 
 | 
         
        (27) Нужного списка номенклатуры разве нет на сервере? Заказ твой не имеет ТЧ например с номенклатурой этой?     
         | 
|||
| 
    32
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:27 
 | 
         
        имеет     
         | 
|||
| 
    33
    
        trad    
     08.10.13 
            ✎
    16:28 
 | 
         
        ну так и возьми этот список оттуда     
         | 
|||
| 
    34
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:29 
 | 
         
        а понял 
 
        
     | 
|||
| 
    35
    
        trad    
     08.10.13 
            ✎
    16:30 
 | 
         
        угу
 
        судя по [Номенклатура $Справочник.Номенклатура] сомневаюсь что понял  | 
|||
| 
    36
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:32 
 | 
         
        я же буду потом выгружать в ТЗ результат и как поиск по таблице будет проходить если там значения будут вида '     I   '?     
         | 
|||
| 
    37
    
        trad    
     08.10.13 
            ✎
    16:35 
 | 
         
        какой такой поиск по ТЗ?
 
        мы же про замену #СписНом на то, что в ТЧ записанной в БД  | 
|||
| 
    38
    
        Mikeware    
     08.10.13 
            ✎
    16:36 
 | 
         
        (25) ну ReconnectNative не зря придуман :-)     
         | 
|||
| 
    39
    
        trad    
     08.10.13 
            ✎
    16:36 
 | 
         
        (38) метод для лентяев - не наш метод :-)     
         | 
|||
| 
    40
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:37 
 | 
        
     | 
|||
| 
    41
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:37 
 | 
         
        +(40) и потом работать с этой ТЗ     
         | 
|||
| 
    42
    
        Z1    
     08.10.13 
            ✎
    16:39 
 | 
         
        (25) в sql2005 исправили     
         | 
|||
| 
    43
    
        trad    
     08.10.13 
            ✎
    16:41 
 | 
         
        (42)Да, но у автора 2000 раз не указано иного     
         | 
|||
| 
    44
    
        trad    
     08.10.13 
            ✎
    16:42 
 | 
         
        (40)верно     
         | 
|||
| 
    45
    
        trad    
     08.10.13 
            ✎
    16:44 
 | 
         
        (40)
 
        можно и по одной ВТ на регистр оставить. Развернуть по фирмам. Сгруппировать по товарам, а "УсловиеПоФирмам" применить при агрегировании. Еще не забыть подумать про дубли строк.  | 
|||
| 
    46
    
        trad    
     08.10.13 
            ✎
    16:45 
 | 
         
        * про дубли строк в ТЧ     
         | 
|||
| 
    47
    
        Z1    
     08.10.13 
            ✎
    16:47 
 | 
         
        (0) а ты можешь сформулировать свою исходную задачу ???     
         | 
|||
| 
    48
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:50 
 | 
         
        (47) Цитирую "Сделать быстро когда проводится заявка покупателя" 
 
        (45) Попробую так не делал еще... (43) да 2000 sp4  | 
|||
| 
    49
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    16:54 
 | 
         
        (48) нет не понял что надо делать     
         | 
|||
| 
    50
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    17:14 
 | 
         
        (45) Развернуть по фирмам
 
        в ВТ (Номенклатура, Фирма) "УсловиеПоФирмам" применить при агрегировании это я так понимаю когда пишем SUM(Рег1.КоличествоОстаток ОстатокПоСкладу) и как тут? :(  | 
|||
| 
    51
    
        trad    
     08.10.13 
            ✎
    17:19 
 | 
         
        sum(case when /*УсловиеПоФирмам*/ then Рег1.КоличествоОстаток else 0 end) ОстатокПоФирме,
 
        sum(Рег1.КоличествоОстаток) ОстатокПоСкладу,  | 
|||
| 
    52
    
        trad    
     08.10.13 
            ✎
    17:21 
 | 
         
        * ну или около того, просто текст как то тяжело у тебя читается     
         | 
|||
| 
    53
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    17:25 
 | 
         
        (51) даааааа
 
        Спасибо :) это очень полезно, я CASE внутри агрегирования еще не использовал все получилось :)  | 
|||
| 
    54
    
        Ёпрст    
     гуру 
    08.10.13 
            ✎
    17:30 
 | 
         
        но лучше кейс не юзать     
         | 
|||
| 
    55
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    17:34 
 | 
         
        почему?     
         | 
|||
| 
    56
    
        Ёпрст    
     гуру 
    08.10.13 
            ✎
    17:36 
 | 
         
        (55) медленно     
         | 
|||
| 
    57
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    17:39 
 | 
         
        (56) медленнее чем брать 2 таблицы регистров дважды? О_о     
         | 
|||
| 
    58
    
        Z1    
     08.10.13 
            ✎
    17:40 
 | 
         
        (56) не факт.
 
        case в клаузе select ничего не стоит case во where скорее всего приведет к скану таблицы  | 
|||
| 
    59
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    17:45 
 | 
         
        (58) интересно, буду знать...
 
        спасибо всем за море полезной информации, новые знания сделали меня немного счастливее :)  | 
|||
| 
    60
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    17:56 
 | 
         
        самое странное что мои 4 запроса из (4) выполняются в 300 раз быстрее чем новый запрос :(
 
        
     | 
|||
| 
    61
    
        Mikeware    
     08.10.13 
            ✎
    18:00 
 | 
         
        (6) кагбэ ничего удивительного. 
 
        вставь условия по товарам в виртуальные таблицы  | 
|||
| 
    62
    
        КонецЦикла    
     08.10.13 
            ✎
    18:01 
 | 
         
        ВсеНечетал, но вот предлагаю ознакомиться (один из вариантов возникновения ошибки)
 
        Подключение занято до получения результатов для другого hstmt  | 
|||
| 
    63
    
        trad    
     08.10.13 
            ✎
    18:02 
 | 
         
        (54) а как лучше?     
         | 
|||
| 
    64
    
        trad    
     08.10.13 
            ✎
    18:06 
 | 
         
        (61) условие по номенклатуре из ON в плане выполнения уйдет в подзапрос от ВТ. Проверено не раз.     
         | 
|||
| 
    65
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    18:19 
 | 
        
так?  | 
|||
| 
    66
    
        Mikeware    
     08.10.13 
            ✎
    18:25 
 | 
         
        (65) inner - тебя же интересует только те товары, что есть в документе. 
 
        Хотя trad против, а я ему верю ибо он крут...  | 
|||
| 
    67
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    18:34 
 | 
         
        (64) условие по номенклатуре такое?
 
        
(66) согласен :)  | 
|||
| 
    68
    
        trad    
     08.10.13 
            ✎
    18:35 
 | 
         
        я не против ибо хуже не будет     
         | 
|||
| 
    69
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    18:55 
 | 
         
        с двумя регистрами
 
        ТЗ = рс10.ВыполнитьИнструкцию(ТекстЗапросаТест); 471 11.342020 51.94 ОстатокНаФирме = рс6.ВыполнитьСкалярный(); 1038 0.202613 0.93 РезервНаФирме = рс7.ВыполнитьСкалярный(); 1038 0.121264 0.56 ОстатокНаСкладе = рс4.ВыполнитьСкалярный(); 519 0.119221 0.55 РезервНаСкладе = рс5.ВыполнитьСкалярный(); 519 0.076368 0.35 с четырьмя замер показывает почти такой же результат ТЗ = рс10.ВыполнитьИнструкцию(ТекстЗапросаТест); 471 12.972334 53.27 ОстатокНаСкладе = рс4.ВыполнитьСкалярный(); 519 0.413398 1.70 ОстатокНаФирме = рс6.ВыполнитьСкалярный(); 1038 0.273864 1.13 РезервНаФирме = рс7.ВыполнитьСкалярный(); 1038 0.124790 0.51 РезервНаСкладе = рс5.ВыполнитьСкалярный(); 519 0.080083 0.33 мои же скалярные все делают намного быстрее :( я не понимаю что тут не так :(  | 
|||
| 
    70
    
        Salimbek    
     08.10.13 
            ✎
    21:11 
 | 
         
        (69) Дальше начинается оптимизация. Первым делом пишешь рс.Отладка(1) до ВыполнитьИнструкцию и смотришь, какой запрос получается в развернутом виде.     
         | 
|||
| 
    71
    
        Z1    
     08.10.13 
            ✎
    21:53 
 | 
         
        (70) да какая оптимизация когда в (67) при повторение строк в табличной части будет задвоение ( затроение остатка ),
 
        чего в 4 нет  | 
|||
| 
    72
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    22:41 
 | 
         
        (71) Почему? О_о (70) да смотрел...     
         | 
|||
| 
    73
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    22:41 
 | 
         
        у меня только резервы кривые еще не победил :(     
         | 
|||
| 
    74
    
        PRO100 NigGaZ    
     08.10.13 
            ✎
    22:48 
 | 
         
        причем запросы которые до SUM(CASE идут по отдельности данные правильные возвращают     
         | 
|||
| 
    75
    
        PRO100 NigGaZ    
     09.10.13 
            ✎
    00:07 
 | 
         
        вернусь я наверное к выполнению скалярных запросов, где есть инструкция что такое курсор и почему не работает при выполнении (4)     
         | 
|||
| 
    76
    
        viktor_vv    
     09.10.13 
            ✎
    01:02 
 | 
         
        Я так тихо подозреваю (4) быстрее, так как нет джойнов и условие по номенклатуре в ВТ типа 
 
        Номенклатура = @ВыбНом быстрее выполнится, чем с джойнами.  | 
|||
| 
    77
    
        Salimbek    
     09.10.13 
            ✎
    08:45 
 | 
         
        (76) Думаешь, что перебрать 1С-кой номенклатуру и отправить 100500 запросов к скулю быстрее, чем перебрать эту номенклатуру скулем (select-ом) и собрать данные одним запросом?
 
        (72) Ну если сам смотрел, то положи текст куда-нибудь на pastebin.com чтобы тоже можно было глянуть  | 
|||
| 
    78
    
        Дык ё    
     09.10.13 
            ✎
    09:28 
 | 
         
        (75) курсоры открывать не только 1спп, но и само 1с умеет. тут с умом подходить нужно :-)     
         | 
|||
| 
    79
    
        PRO100 NigGaZ    
     09.10.13 
            ✎
    12:56 
 | 
         
        Да, как показал вчерашний день получить все сразу происходит в  8 раз медленнее чем выполняя скалярные запросы :(     
         | 
|||
| 
    80
    
        Salimbek    
     09.10.13 
            ✎
    13:10 
 | 
         
        (79) Ты ошибаешься, проблема в неоптимальном плане запроса. И, чтобы посоветовать что-то дельное, я и прошу выложить код из (70) на ПастеБин     
         | 
|||
| 
    81
    
        Ёпрст    
     гуру 
    09.10.13 
            ✎
    13:43 
 | 
         
        |Where (Товары.IDDOC = :ВыбДок) 
 
        вот это унутрь ВТ запихни, для начала.  | 
|||
| 
    82
    
        viktor_vv    
     09.10.13 
            ✎
    14:44 
 | 
         
        (81) Так там в (67) для верности везде понаставлено :).
 
        | ,inner join $ДокументСтроки.ЗаявкаПокупателя AS Товары With (NOLOCK) on $Товары.Номенклатура = Номенклатура | ,(Товары.IDDOC = :ВыбДок) разве что из условия ВТ в условие соединение перенести "Товары.IDDOC = :ВыбДок", по идее однояйственно, но таки лучше туда.  | 
|||
| 
    83
    
        Salimbek    
     09.10.13 
            ✎
    14:57 
 | 
         
        х.з. я бы сначала простейший запрос с одним регистром бы только потестил, с разными вариантами наложения фильтров, и через временные таблицы попробовал бы, и соединениями различными. Как нашел бы оптимальный по скорости вариант, остальные регистры начал бы подцеплять.     
         | 
|||
| 
    84
    
        PRO100 NigGaZ    
     09.10.13 
            ✎
    18:17 
 | 
         
        ок попробую...     
         | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |