Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Ошибка при  выполнении запроса (число прочтений - 3371 )
mult_ru
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 2
Зарегистрирован: 03. Февраля 2011
Ошибка при  выполнении запроса
03. Февраля 2011 :: 09:08
Печать  
День добрый помогите разобраться со следующей проблемой.

Есть рабочий запрос который выбирал из базы наименование продукта, который задается в форме.

Необходимо его модернизировать чтобы он выбирал несколько наименований продукта которые задаются в форме Списком.

Я его поправил и при 1 значении в списке он работает как только их становиться больше запрос не выполняется.

Просьба подскажите что я делаю не так...

Сам запрос :
     СпрТекстЗапроса_Товар = "
     |SELECT
     |      id      AS [Товар $Справочник.Номенклатура]
     |FROM
     |      $Справочник.Номенклатура
     |";
     
     СпрТекстЗапроса_Товар = СпрТекстЗапроса_Товар + "WHERE (";                   
     Для Номер = 1 По ПродСписок.РазмерСписка() Цикл
           Тмп="";
           Если Номер=1 Тогда
                 ТмпЗнач1 = ПродСписок.ПолучитьЗначение(Номер, Тмп);
                 СпрТекстЗапроса_Товар = СпрТекстЗапроса_Товар + "(id = :ТмпЗнач1)";
                 SQLSession.УстановитьТекстовыйПараметр("ТмпЗнач1",  МетаД.ЗначениеВСтрокуБД(ТмпЗнач1));
           Иначе
                 ТмпЗнач2 = ПродСписок.ПолучитьЗначение(Номер, Тмп);
                 СпрТекстЗапроса_Товар = СпрТекстЗапроса_Товар + " AND (id = :ТмпЗнач2)";
                 SQLSession.УстановитьТекстовыйПараметр("ТмпЗнач2",  МетаД.ЗначениеВСтрокуБД(ТмпЗнач2));
           КонецЕсли;
     КонецЦикла;
    СпрТекстЗапроса_Товар = СпрТекстЗапроса_Товар + ")";      
     
     if SQLSession.Открыть(СпрТекстЗапроса_Товар) = 0 then
           Сообщить(SQLSession.GetLastError());
           Возврат;
     endif;

     сзТовары      = SQLSession.ПолучитьЗначенияСЗ(1);
     SQLSession.Закрыть();

Заранее благодарю...
  
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Ошибка при  выполнении запроса
Ответ #1 - 03. Февраля 2011 :: 09:10
Печать  
Пользуй УложитьСписокОбъектов
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Ошибка при  выполнении запроса
Ответ #2 - 03. Февраля 2011 :: 09:13
Печать  
(0) вместо условия AND надо использовать условие OR
а еще лучше делай как сказано в (1)
  
Наверх
 
IP записан
 
mult_ru
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 2
Зарегистрирован: 03. Февраля 2011
Re: Ошибка при  выполнении запроса
Ответ #3 - 03. Февраля 2011 :: 09:14
Печать  
Можно пример ? И если не сложно ссылку на информацию по прямым SQl запросам
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Ошибка при  выполнении запроса
Ответ #4 - 03. Февраля 2011 :: 09:19
Печать  
mult_ru писал(а) 03. Февраля 2011 :: 09:14:
Можно пример ? И если не сложно ссылку на информацию по прямым SQl запросам

примеров на этом форуме очень много.
информация смотри статью
http://www.script-coding.com/Direct_queries.html
  
Наверх
 
IP записан
 
Sem_chik
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 13
Местоположение: Саратов
Зарегистрирован: 11. Октября 2010
Пол: Мужской
Re: Ошибка при  выполнении запроса
Ответ #5 - 04. Февраля 2011 :: 12:00
Печать  
Товар IN (SELECT Val FROM #Nom)

рс.УложитьСписокОбъектов(ВыбТовары,"#Nom","Номенклатура")

ВыбТовары -реквизит
"Номенклатура" =название справочника

Вот что-то типо этого.
  
Наверх
ICQ  
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ошибка при  выполнении запроса
Ответ #6 - 07. Февраля 2011 :: 04:49
Печать  
Или же, если "УложитьСписокОбъектов" не нравится, можно сделать вот так:

стрУсловие = "";
Для Номер = 1 По ПродСписок.РазмерСписка() Цикл
   стрУсловие = стрУсловие + ", '" + МетаД.ЗначениеВСтрокуБД(ПродСписок.ПолучитьЗначение(й)) + "'"; // не путаем ' и "
КонецЦикла;
СпрТекстЗапроса_Товар = СпрТекстЗапроса_Товар + "WHERE Id IN (" + Сред(стрУсловие, 3) + ")";
  
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Ошибка при  выполнении запроса
Ответ #7 - 07. Февраля 2011 :: 08:03
Печать  
Satans Claws писал(а) 07. Февраля 2011 :: 04:49:
Или же, если "УложитьСписокОбъектов" не нравится, можно сделать вот так:

стрУсловие = "";
Для Номер = 1 По ПродСписок.РазмерСписка() Цикл
  стрУсловие = стрУсловие + ", '" + МетаД.ЗначениеВСтрокуБД(ПродСписок.ПолучитьЗначение(й)) + "'"; // не путаем ' и "
КонецЦикла;
СпрТекстЗапроса_Товар = СпрТекстЗапроса_Товар + "WHERE Id IN (" + Сред(стрУсловие, 3) + ")";

Такой вариант не всегда будет работать (сейчас не помню причин), а с подзапросом - всегда! ... то ли в количестве вариантов дело, то ли еще в чем - не помню ... скорее всего в количестве, и как следствие - длина строки запроса...
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ошибка при  выполнении запроса
Ответ #8 - 08. Февраля 2011 :: 11:38
Печать  
Dmitry The Wing писал(а) 07. Февраля 2011 :: 08:03:
Такой вариант не всегда будет работать (сейчас не помню причин), а с подзапросом - всегда! ... то ли в количестве вариантов дело, то ли еще в чем - не помню ... скорее всего в количестве, и как следствие - длина строки запроса...


До 100 значений скуль вполне нормально переваривает.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Ошибка при  выполнении запроса
Ответ #9 - 08. Февраля 2011 :: 11:58
Печать  
Satans Claws писал(а) 07. Февраля 2011 :: 04:49:
Или же, если "УложитьСписокОбъектов" не нравится, можно сделать вот так:

стрУсловие = "";
Для Номер = 1 По ПродСписок.РазмерСписка() Цикл
  стрУсловие = стрУсловие + ", '" + МетаД.ЗначениеВСтрокуБД(ПродСписок.ПолучитьЗначение(й)) + "'"; // не путаем ' и "
КонецЦикла;
СпрТекстЗапроса_Товар = СпрТекстЗапроса_Товар + "WHERE Id IN (" + Сред(стрУсловие, 3) + ")";

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

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


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ошибка при  выполнении запроса
Ответ #10 - 09. Февраля 2011 :: 05:55
Печать  
Z1 писал(а) 08. Февраля 2011 :: 11:58:
Зачем это советовать
а работать будет медленее - хотя бы за счет формирования врем. таблицы.
б работать будет и неправильно если элемент списка  будет группой.



Зависит от исходной задачи (если посмотришь начало темы, там собирается именно в аналог IN(). Хотя, не исключаю, что автор просто не закладывался на то, что нужно проверять вхождение в группы.) Если задача именно такова, что IN(значение, знечение, ...) - достаточно, то 1) это читабельнее, чем использование временных таблиц, 2) как я уже говорил - на небольших списках работает отлично. Небольшие списки - это порядка 50..100 значений. Опять же - покажите мне человека, собственноручно забившего в фильтр 50 одиночных значений (именно одиночных). Ситуация достаточно редкая (а если не редкая - то, скорее всего, можно хорошо задуматься над структурированием данных - но это уже начинается эзотерика) .

PS не понял про "за счет формирования врем. таблицы". IN(значение, значение,...) никаких временных таблиц не генерирует (по крайней мере - на упомянутых выше ~50 значениях). Можете покурить планы запросов.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Ошибка при  выполнении запроса
Ответ #11 - 09. Февраля 2011 :: 06:28
Печать  
Satans Claws писал(а) 09. Февраля 2011 :: 05:55:
Z1 писал(а) 08. Февраля 2011 :: 11:58:
Зачем это советовать
а работать будет медленее - хотя бы за счет формирования врем. таблицы.
б работать будет и неправильно если элемент списка  будет группой.



Зависит от исходной задачи (если посмотришь начало темы, там собирается именно в аналог IN(). Хотя, не исключаю, что автор просто не закладывался на то, что нужно проверять вхождение в группы.) Если задача именно такова, что IN(значение, знечение, ...) - достаточно, то 1) это читабельнее, чем использование временных таблиц, 2) как я уже говорил - на небольших списках работает отлично. Небольшие списки - это порядка 50..100 значений. Опять же - покажите мне человека, собственноручно забившего в фильтр 50 одиночных значений (именно одиночных). Ситуация достаточно редкая (а если не редкая - то, скорее всего, можно хорошо задуматься над структурированием данных - но это уже начинается эзотерика) .

PS не понял про "за счет формирования врем. таблицы". IN(значение, значение,...) никаких временных таблиц не генерирует (по крайней мере - на упомянутых выше ~50 значениях). Можете покурить планы запросов.


ты меня не понял
я имел ввиду следущее
формирования списка строковых констант  для предиката in
из языка 1с будет гораздо медленее работать чем аналогичные
действия по занесению тех же значений из списка значений(УложитьСписокОбъектов) выполняющийся на с++.
Т.е. если и применять твой способ то если значений не более 10.
речь не идет о правильности или не правильности того что ты предложил
а о том что это не эфиктивное решение с точки зрения общей производительности.

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


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ошибка при  выполнении запроса
Ответ #12 - 09. Февраля 2011 :: 11:17
Печать  
Z1 писал(а) 09. Февраля 2011 :: 06:28:
ты меня не понял
я имел ввиду следущее
формирования списка строковых констант  для предиката in
из языка 1с будет гораздо медленее работать чем аналогичные
действия по занесению тех же значений из списка значений(УложитьСписокОбъектов) выполняющийся на с++.
Т.е. если и применять твой способ то если значений не более 10.
речь не идет о правильности или не правильности того что ты предложил
а о том что это не эфиктивное решение с точки зрения общей производительности.


Эммм...
Ты непосредственно про коннектацию строк, или про скорость работы метода ЗначениеВСтрокуБД()?

Если касательно ЗначениеВСтрокуБД() - то в такие дебри я никогда не лез.
Но думаю, что той разницы - такие доли секунды, что хоть как-то будет заметно лишь на тысячах объектов.
И оптимизировать эти доли секунды - работа, в общем-то, абсолютно неблагодарная.
Плюс, не стоит забывать такой момент: ладно, если эти объекты есть в виде уже готового списка значений. Но если предварительно будет нужно набивать этот СЗ - то еще бабушка надвое сказала, что выигрышь от УложитьСписокОбъектов() не проиграет времени заполнения СЗ.

Более того, имеется опыт разработки (и эксплуатации пользователями) одной высоконагруженной базы, в которой, на вскидку, вся (а если не вся - то 99%) информации собирается прямыми запросами. И я не помню, чтоб там хоть где-то использовалось УложитьСписокОбъектов (т.е. если и используется - то это исключительно-единичные случаи).

Опять же - отчасти это филисофский вопрос организации данных. При нормальной организации, редко когда будет нужно передавать в качестве параметров крупные списки.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Ошибка при  выполнении запроса
Ответ #13 - 09. Февраля 2011 :: 12:32
Печать  
Satans Claws писал(а) 09. Февраля 2011 :: 11:17:
Z1 писал(а) 09. Февраля 2011 :: 06:28:
ты меня не понял
я имел ввиду следущее
формирования списка строковых констант  для предиката in
из языка 1с будет гораздо медленее работать чем аналогичные
действия по занесению тех же значений из списка значений(УложитьСписокОбъектов) выполняющийся на с++.
Т.е. если и применять твой способ то если значений не более 10.
речь не идет о правильности или не правильности того что ты предложил
а о том что это не эфиктивное решение с точки зрения общей производительности.


Эммм...
Ты непосредственно про коннектацию строк, или про скорость работы метода ЗначениеВСтрокуБД()?

И то и другое



Цитата:
Если касательно ЗначениеВСтрокуБД() - то в такие дебри я никогда не лез.
Но думаю, что той разницы - такие доли секунды, что хоть как-то будет заметно лишь на тысячах объектов.
И оптимизировать эти доли секунды - работа, в общем-то, абсолютно неблагодарная.

ИХМО Оптимизировать стоит(хотя каждый раъработчик решает сам ).
Пример в соседней ветке по проведени проверить остатки в модуле проведения
где каждая секунда (даже милисекунда ох как дорого стоит).
Как бы делал я.
1.Получить ТЗ товар количество ( без услуг )
2.Сворачиваем ТЗ
3.Из этой ТЗ получаем список значений и по нему формируем СписокЗначений.
Этот списокзначений используем для УложитьСписокОбъектов
(одно из моих пожеланий развития 1с++(непринятых) было чтобы можно было УложитьТаблицуОбъектов)
4. Пишем запрос возвращающий остатки с противоположным знаком в туже самую таблицу)
5. Сворачиваем ТЗ
6. Где плюсы там на самом деле не прошел контроль остатков




Цитата:
Более того, имеется опыт разработки (и эксплуатации пользователями) одной высоконагруженной базы,
в которой, на вскидку, вся (а если не вся - то 99%) информации собирается прямыми запросами.
И я не помню, чтоб там хоть где-то использовалось УложитьСписокОбъектов
(т.е. если и используется - то это исключительно-единичные случаи).

ну и как в этом случае обрабатываются группы?
Если на клиенте то это неитересно.




Цитата:
Опять же - отчасти это филисофский вопрос организации данных. При нормальной организации, редко когда будет нужно передавать в качестве параметров крупные списки.

Смотри вышеописаный пример контроль остатков расходной  накладной.
Количество позиций в расходной накладной может быть и большим и превышать сто строк.

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


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ошибка при  выполнении запроса
Ответ #14 - 09. Февраля 2011 :: 12:39
Печать  
Z1 писал(а) 09. Февраля 2011 :: 12:32:
ну и как в этом случае обрабатываются группы?
Если на клиенте то это неитересно.

Обработка групп, в основном, нужна только для отчетов - а для отчетов есть специальный класс, который набивает #ВремТаб рекурсивным запросом.


Цитата:
Цитата:
Опять же - отчасти это филисофский вопрос организации данных. При нормальной организации, редко когда будет нужно передавать в качестве параметров крупные списки.

Смотри вышеописаный пример контроль остатков расходной  накладной.
Количество позиций в расходной накладной может быть и большим и превышать сто строк.

Для документов - джойн на выборку из таблицы строк документов. Все остальное - от лукавого по определению.


Вот, недавно общался с одним очень продвинутым проггером (можете почитать его посты под тэгом 1С).
http://speshuric.livejournal.com/173283.html?thread=704483#t704483
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать