Имя: Пароль:
1C
1C 7.7
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

    ТекстЗапросаТест = "
    |SET NOCOUNT ON
    |DECLARE @ВыбНом char(9)
    |SET @ВыбНом = ?
    |Select Sum(Остаток) Остаток, Sum(Резерв) Резерв
    |From (
    |SELECT Sum(Рег1.КоличествоОстаток) Остаток, 0 Резерв
    |FROM $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + ",,(Номенклатура = @ВыбНом) AND (Склад = :ВыбСклад)"
    + ?(ПустоеЗначение(УсловиеПоФирмам) = 0," AND " + УсловиеПоФирмам,"") + ",,) AS Рег1
    |UNION ALL
    |SELECT 0 Остаток, Sum(Рег2.КоличествоОстаток) Резерв
    |FROM $РегистрОстатки.РезервыТМЦ(" + УсловиеПоДате  + ",,(Номенклатура = @ВыбНом) AND (Склад = :ВыбСклад)"
    + ?(ПустоеЗначение(УсловиеПоФирмам) = 0," AND " + УсловиеПоФирмам,"") + ",,) AS Рег2) AS Подзапрос";

    ТекстЗапросаОстатки = "
    |DECLARE @ВыбНом char(9)
    |SET @ВыбНом = ?
    |SELECT Sum(Рег.КоличествоОстаток) Остаток
    |FROM $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + ",,(Номенклатура = @ВыбНом) AND (Склад = :ВыбСклад)"
    + ?(ПустоеЗначение(УсловиеПоФирмам) = 0," AND " + УсловиеПоФирмам,"") + ",,) AS Рег";

    рс4.УстановитьТекстовыйПараметр("ВыбСклад", Склад);
    рс4.Подготовить(ТекстЗапросаОстатки);
    рс4.ДобПараметр(1,14,9,0);
    ТекстЗапросаРезервы = СтрЗаменить(ТекстЗапросаОстатки, "ОстаткиТМЦ", "РезервыТМЦ");
    рс5.УстановитьТекстовыйПараметр("ВыбСклад", Склад);
    рс5.Подготовить(ТекстЗапросаРезервы);
    рс5.ДобПараметр(1,14,9,0);
    ТекстЗапросаОстатки = СтрЗаменить(ТекстЗапросаОстатки, " AND (Склад = :ВыбСклад)", "");
    рс6.Подготовить(ТекстЗапросаОстатки);
    рс6.ДобПараметр(1,14,9,0);


    рс10.УстановитьТекстовыйПараметр("ВыбСклад", Склад);
    рс10.Подготовить(ТекстЗапросаТест);
    рс10.ДобПараметр(1,14,9,0);

//далее выполняется цикл по товарам в документе и вызывается процедура в каждом шаге цикла
    Если ПустоеЗначение(ТекСклад) = 0 Тогда
        
        рс4.УстПараметр(1, ТекНоменклатура);
        ОстатокНаСкладе = рс4.ВыполнитьСкалярный();
        рс5.УстПараметр(1, ТекНоменклатура);
        РезервНаСкладе = рс5.ВыполнитьСкалярный();
        рс10.УстПараметр(1, ТекНоменклатура); //это тестовый кусок кода для уменьшения обрашений к серверу
        Рез = рс10.ВыполнитьСкалярный(); //
        Сообщить(Рез.Остаток); //
        Сообщить(Рез.Резерв); //
        Рез = ""; //конец тестового кода
        МожноСделатьРезервНаСкладе = Макс(0,Мин(КолРезерва,(ОстатокНаСкладе - РезервНаСкладе)));

        // проверка резерва на складе
        Если (МожноСделатьРезервНаСкладе < КолРезерва)
        и    (ВидОперации = Перечисление.ВидыОперацийЗаявок.НаСклад)
        Тогда
            глНеПроводить(Контекст,"На складе нет нужного свободного количества ТМЦ "+ТекНоменклатура.Наименование
            +". "+РазделительСтрок+"    Всего осталось "+Строка(ОстатокНаСкладе)+" "+ТекНоменклатура.БазоваяЕдиница
            +". "+РазделительСтрок+"    Зарезервировано по выписанным Заявкам "+Строка(РезервНаСкладе)
            +" "+ТекНоменклатура.БазоваяЕдиница+"."+РазделительСтрок+"Требуемое количество "+Строка(КолРезерва)+" "+ТекНоменклатура.БазоваяЕдиница);
            Возврат 0;
        КонецЕсли;                
    КонецЕсли;
        
    // теперь проверим по фирме в целом
    ОстатокНаФирме = 0;
    РезервНаФирме  = 0;
            
    рс6.УстПараметр(1, ТекНоменклатура);
    ОстатокНаФирме = рс6.ВыполнитьСкалярный(); //тут возникает эта ошибка

и если убрать тестовый код то все норм...
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 = СоздатьОбъект("ODBCRecordSet"); //Замена ВремЗаявки
    рс2 = СоздатьОбъект("ODBCRecordSet"); //Замена ВремЗаказыЗаявки
    рс3 = СоздатьОбъект("ODBCRecordSet"); //Замена ВремРезервыТМЦ
    рс4 = СоздатьОбъект("ODBCRecordSet"); //Замена по остаткиТМЦ с учетом склада
    рс5 = СоздатьОбъект("ODBCRecordSet"); //Замена по РезервыТМЦ с учетом склада
    рс6 = СоздатьОбъект("ODBCRecordSet"); //Замена по остаткиТМЦ без учета склада
    рс7 = СоздатьОбъект("ODBCRecordSet"); //Замена по РезервыТМЦ без учета склада
    рс8 = СоздатьОбъект("ODBCRecordSet"); //Замена по Заказы
    рс9 = СоздатьОбъект("ODBCRecordSet"); //Замена по ЗаказыЗаявки
    рс10 = СоздатьОбъект("ODBCRecordSet"); //тест замена остаткиТМЦ с учетом склада и РезервыТМЦ с учетом склада

и все запросы с параметрами и выполняются скалярно, кроме первых трех, они возвращают таблицы и только 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
Так же будет лучше всего?

    рс10 = СоздатьОбъект("ODBCRecordSet");
    ТекстЗапросаТест = "
    |SET NOCOUNT ON
    |SELECT distinct Товары.val [Номенклатура $Справочник.Номенклатура]
    |    , Рег1.КоличествоОстаток ОстатокПоСкладу
    |    , Рег2.КоличествоОстаток РезервПоСкладу
    |    , Рег3.КоличествоОстаток ОстатокПоФирме
    |    , Рег4.КоличествоОстаток РезервПоФирме
    |FROM #СписНом as Товары
    |Left Join $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + ",,(Склад = :ВыбСклад)"
    + ?(ПустоеЗначение(УсловиеПоФирмам) = 0," AND " + УсловиеПоФирмам,"") + ",Номенклатура,Количество) AS Рег1 on Товары.val = Рег1.Номенклатура
    |Left Join $РегистрОстатки.РезервыТМЦ(" + УсловиеПоДате  + ",,(Склад = :ВыбСклад)"
    + ?(ПустоеЗначение(УсловиеПоФирмам) = 0," AND " + УсловиеПоФирмам,"") + ",Номенклатура,Количество) AS Рег2 on Товары.val = Рег2.Номенклатура
    |Left Join $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + ",," + УсловиеПоФирмам + ",Номенклатура,Количество) AS Рег3 on Товары.val = Рег3.Номенклатура
    |Left Join $РегистрОстатки.РезервыТМЦ(" + УсловиеПоДате  + ",," + УсловиеПоФирмам + ",Номенклатура,Количество) AS Рег4 on Товары.val = Рег4.Номенклатура
    |";
    рс10.УложитьСписокОбъектов(СписокНоменклатуры, "#СписНом");
    рс10.УстановитьТекстовыйПараметр("ВыбДата", ПозицияДокумента);
    рс10.УстановитьТекстовыйПараметр("ВыбСклад", Склад);
    ТЗ = рс10.ВыполнитьИнструкцию(ТекстЗапросаТест);
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
Тогда так?

        Условия ="(";
        Для Н=1 По СписокНоменклатуры.РазмерСписка() Цикл
            Условия = Условия + "'" + МД.ЗначениеВСтрокуБД(СписокНоменклатуры.ПолучитьЗначение(Н)) + ?(Н=СписокНоменклатуры.РазмерСписка(),"')","',");
        КонецЦикла;
        СписокНоменклатуры = "(Номенклатура IN " + Условия + ")";
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
а понял

SELECT $ЗаявкаПокупателяСтроки.Номенклатура [Номенклатура $Справочник.Номенклатура]
FROM $ДокументСтроки.ЗаявкаПокупателя AS ЗаявкаПокупателяСтроки With (NOLOCK)
WHERE (ЗаявкаПокупателяСтроки.IDDOC = :ВыбДок)
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

    ТекстЗапросаТест = "
    |SET NOCOUNT ON
    |SELECT Товары.Номенклатура [Номенклатура $Справочник.Номенклатура]
    |    , Рег1.КоличествоОстаток ОстатокПоСкладу
    |    , Рег2.КоличествоОстаток РезервПоСкладу
    |    , Рег3.КоличествоОстаток ОстатокПоФирме
    |    , Рег4.КоличествоОстаток РезервПоФирме
    |FROM $ДокументСтроки.ЗаявкаПокупателя AS Товары With (NOLOCK)
    |Left Join $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + ",,(Склад = :ВыбСклад)"
    + ?(ПустоеЗначение(УсловиеПоФирмам) = 0," AND " + УсловиеПоФирмам,"") + ",Номенклатура,Количество) AS Рег1 on Товары.Номенклатура = Рег1.Номенклатура
    |Left Join $РегистрОстатки.РезервыТМЦ(" + УсловиеПоДате  + ",,(Склад = :ВыбСклад)"
    + ?(ПустоеЗначение(УсловиеПоФирмам) = 0," AND " + УсловиеПоФирмам,"") + ",Номенклатура,Количество) AS Рег2 on Товары.Номенклатура = Рег2.Номенклатура
    |Left Join $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + ",," + УсловиеПоФирмам + ",Номенклатура,Количество) AS Рег3 on Товары.Номенклатура = Рег3.Номенклатура
    |Left Join $РегистрОстатки.РезервыТМЦ(" + УсловиеПоДате  + ",," + УсловиеПоФирмам + ",Номенклатура,Количество) AS Рег4 on Товары.Номенклатура = Рег4.Номенклатура
    |Where (Товары.IDDOC = :ВыбДок)";
    //рс10.УложитьСписокОбъектов(СписокНоменклатуры, "#СписНом");
    рс10.УстановитьТекстовыйПараметр("ВыбДок", ТекущийДокумент());
    рс10.УстановитьТекстовыйПараметр("ВыбДата", ПозицияДокумента);
    рс10.УстановитьТекстовыйПараметр("ВыбСклад", Склад);
    рс10.Отладка(1);
    ТЗ = рс10.ВыполнитьИнструкцию(ТекстЗапросаТест);
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 раз быстрее чем новый запрос :(

    ТекстЗапросаТест = "
    |SET NOCOUNT ON
    |SELECT $Товары.Номенклатура [Номенклатура $Справочник.Номенклатура]
    |    , SUM(CASE WHEN Рег1.Склад = :ВыбСклад THEN Рег1.КоличествоОстаток ELSE 0 END) ОстатокПоСкладу
    |    , SUM(CASE WHEN Рег2.Склад = :ВыбСклад THEN Рег2.КоличествоОстаток ELSE 0 END) РезервПоСкладу
    |    , SUM(CASE WHEN Рег1." + УсловиеПоФирмам + " THEN Рег1.КоличествоОстаток ELSE 0 END) ОстатокПоФирме
    |    , SUM(CASE WHEN Рег2." + УсловиеПоФирмам + " THEN Рег2.КоличествоОстаток ELSE 0 END) РезервПоФирме
    |FROM $ДокументСтроки.ЗаявкаПокупателя AS Товары With (NOLOCK)
    |Left Join $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + ",,,(Номенклатура, Фирма, Склад),Количество) AS Рег1 on $Товары.Номенклатура = Рег1.Номенклатура
    |Left Join $РегистрОстатки.РезервыТМЦ(" + УсловиеПоДате  + ",,,(Номенклатура, Фирма, Склад),Количество) AS Рег2 on $Товары.Номенклатура = Рег2.Номенклатура
    |Where (Товары.IDDOC = :ВыбДок)

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

|Left Join $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + ",Left join $ДокументСтроки.ЗаявкаПокупателя AS Товары on $Товары.Номенклатура = Номенклатура
    |                                                        ,,(Номенклатура, Фирма, Склад),Количество) AS Рег1 on $Товары.Номенклатура = Рег1.Номенклатура

так?
66 Mikeware
 
08.10.13
18:25
(65) inner - тебя же интересует только те товары, что есть в документе.
Хотя trad против, а я ему верю ибо он крут...
67 PRO100 NigGaZ
 
08.10.13
18:34
(64) условие по номенклатуре такое?

    ТекстЗапросаТест = "
    |SET NOCOUNT ON
    |SELECT $Товары.Номенклатура [Номенклатура $Справочник.Номенклатура]
    |    , SUM(CASE WHEN Рег1.Склад = :ВыбСклад THEN Рег1.КоличествоОстаток ELSE 0 END) ОстатокПоСкладу
    |    , SUM(CASE WHEN Рег2.Склад = :ВыбСклад THEN Рег2.КоличествоОстаток ELSE 0 END) РезервПоСкладу
    |    , SUM(CASE WHEN Рег1." + УсловиеПоФирмам + " THEN Рег1.КоличествоОстаток ELSE 0 END) ОстатокПоФирме
    |    , SUM(CASE WHEN Рег2." + УсловиеПоФирмам + " THEN Рег2.КоличествоОстаток ELSE 0 END) РезервПоФирме
    |FROM $ДокументСтроки.ЗаявкаПокупателя AS Товары With (NOLOCK)
    |Left Join $РегистрОстатки.ОстаткиТМЦ(" + УсловиеПоДате  + "
    |                                    ,inner join $ДокументСтроки.ЗаявкаПокупателя AS Товары With (NOLOCK) on $Товары.Номенклатура = Номенклатура
    |                                    ,(Товары.IDDOC = :ВыбДок)
    |                                    ,(Номенклатура, Фирма, Склад)
    |                                    ,Количество) AS Рег1 on $Товары.Номенклатура = Рег1.Номенклатура
    |Left Join $РегистрОстатки.РезервыТМЦ(" + УсловиеПоДате  + "
    |                                    ,inner join $ДокументСтроки.ЗаявкаПокупателя AS Товары With (NOLOCK) on $Товары.Номенклатура = Номенклатура
    |                                    ,(Товары.IDDOC = :ВыбДок)
    |                                    ,(Номенклатура, Фирма, Склад),Количество) AS Рег2 on $Товары.Номенклатура = Рег2.Номенклатура
    |Where (Товары.IDDOC = :ВыбДок)    
    |Group by $Товары.Номенклатура";

(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
ок попробую...