Прямые запросы к базе данных

Тема в разделе "1C и всё что с ней связано", создана пользователем vitfil, 6 окт 2009.

Наш партнер Genesis Hackspace
  1. vitfil

    vitfil IT-интегратор

    Регистрация:
    2 апр 2004
    Сообщения:
    2.062
    Симпатии:
    0
    В этой теме вы задаете вопросы по использованию прямых запросов к базам данных... Мы отвечаем. Все обсуждения будут удаляться. Останутся только вопросы и варианты решения.

    Для затравки:
    Где взять компоненту, позволяющую использовать прямые запросы и приведение метаданных у именам таблиц 1С?
    На сайте www.1cpp.ru
    На этом же сайте находится документация, примеры и достаточно хороший форум.
    Почему создан этот топик? Потому что вам лень искать в форуме на сайте производителя компоненты или читать документацию.

    Как загрузить компоненту?
    ЗагрузитьВнешнююКомпоненту(ИмяКаталога+"1cpp.dll");

    Зачем все это нужно?
    1. 1С некоторые запросы трансформирует (в угоду универсальности и в ущерб производительности) в огромное количество мелких подзапросов.
    2. Невозможность получить некоторые данные в одном штатном запросе 1С.
    3. Невозможность сформировать некоторые структуры данных штатными средствами 1С.
    4. Невозможность реализовать некоторый необходимый функционал штатными средствами 1С.
    5. У меня ужасно все тормозит, но я не хочу переходить с 7.7 на 8.х по соображениям стоимости внедрения (ничего личного к 8.х).

    Почему вам это не нужно?
    Потому что вас все устраивает!

    Могу ли я получать данные из других СУБД?
    Да!

    Могу ли я получать данные из разных баз в одном запросе?
    Да!

    Для чего все это надо модератору форума?
    1. Модератор страдает навязчивой идеей необходимости распространения знаний.
    2. Модератор страдает неизлечимой графоманией в области интересных ему тем.
    3. Модератора достали вопросы типа: как мне сделать выборку двух (двадцати) документов нужного мне вида?
    4. Модератор просто хороший человек, который хочет поделиться с вами своими опытом и знаниями.
    5. Модератор форума искренне надеется, что подобная тема привлечет дополнительное количество программистов филантропов, готовых делиться своим опытом и знаниями.
    6. Модератор в душе уверен, что в один момент его помянут фразой "Он был настоящим программистом!".

    Ответят ли вам здесь более квалифицировано, чем на сайте компоненты?
    Невероятно сложный вопрос... Возможно да, возможно, нет.
    В любом случае, ответом на ваш вопрос будет либо личный опыт и знания, либо информация полученная из документации или сайтов названных выше. Что это означает? Отвечу цитатой из официального письма, которое мне удалось прочесть лет 10 назад в одной из фирм-франчайзи: "Конфигурация "Торговля и Склад" является примером ОДНОЙ ИЗ ВОЗМОЖНЫХ реализаций задачи по оперативному и складскому учету с использованием компоненты "Оперативный учет""...
     
  2. LEVENTENOK

    LEVENTENOK Гость

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

    у меня пока это сделано примерно так:

    Код ( (Unknown Language)):
    Запрос = СоздатьОбъект("Запрос");

    ТекстЗапроса =
    "//{{ЗАПРОС(Сформировать)
    |Период с ВыбНачПериода по ВыбКонПериода;
    |Товар = Регистр.ОстаткиТоваров.Товар;
    |Склад = Регистр.ОстаткиТоваров.Склад;
    |Серии = Регистр.ОстаткиТоваров.Серия;
    |ЦехУпак = Регистр.ОстаткиТоваров.Серия.КолЦУ;
    |КонтрЦена = Регистр.ОстаткиТоваров.Серия.КонтрЦена;
    |ОстатокТовара = Регистр.ОстаткиТоваров.ОстатокТовара;
    |Условие (Товар в Список);
    |Условие (Склад В СкладСписок);
    |Функция КвоНачОст = НачОст(ОстатокТовара);
    |Группировка Товар без групп Упорядочить по Товар.Наименование;
    |Группировка День;
    |Группировка Склад;
    |Группировка Серии;";

    Запрос.Выполнить(ТекстЗапроса);
    Пока Запрос.Группировка(1)=1 Цикл
    Пока Запрос.Группировка(2)=1 Цикл
    Пока Запрос.Группировка(3) =1 Цикл;
    Пока Запрос.Группировка(4) =1 Цикл;
    ТЗ1.НоваяСтрока();
    ТЗ1.Товар = Запрос.Товар;
    ТЗ1.Склад = Запрос.Склад;
    ТЗ1.Серии = Запрос.Серии;
    ТЗ1.КонтрЦена = Запрос.КонтрЦена;
    ТЗ1.День = Запрос.День;
    ТЗ1.КвоНачОст = Запрос.КвоНачОст;
    ТЗ1.ЦехУпак = Запрос.ЦехУпак;
    КонецЦикла;
    КонецЦикла;
    КонецЦикла;
    КонецЦикла;  

    ТЗ1.Свернуть("Товар, Склад, День, КонтрЦена, ЦехУпак","КвоНачОст");

    ТЗ.ВыбратьСтроки();
    Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    КолДН = 0;
    ТЗ1.ВыбратьСтроки();
    Для i=1 по ТЗ1.КоличествоСтрок() цикл
    ТЗ1.ПолучитьСтрокуПоНомеру(i);
    Если ТЗ.Товар <> ТЗ1.Товар Тогда
    Продолжить;
    КонецЕсли;
    КолДН = КолДН + 1;
    КонецЦикла;
    ТЗ.КолДн = КолДН;  
    КонецЦикла;
     
  3. vitfil

    vitfil IT-интегратор

    Регистрация:
    2 апр 2004
    Сообщения:
    2.062
    Симпатии:
    0
    Офтоп удалил. Далее привожу пример прямого запроса. Нужные вам измерения добавите по образу и подобию.
    Код (Text):
    select
    Рег.Товар as [Товар $Справочник.Номенклатура]
    , Рег.Склад as [Склад $Справочник.МестаХранения]
    , Рег.ОстатокТовараНачальныйОстаток as КвоНачОст
    , Рег.Период as Период
    from
    $РегистрОстаткиОбороты.ОстаткиТоваров(:НачДата,:КонДата~,День,
    inner join $Справочник.Номенклатура as ТовРег with (nolock) on ТовРег.id = Товар and ТовРег.id in (select val from #СписокТоваров)
    inner join $Справочник.МестаХранения as СклРег with (nolock) on СклРег.id = Склад and СклРег.id in (select val from #СписокСкладов),
    ,
    (Товар,Склад), (ОстатокТовара)) as Рег
    left join
    $Справочник.Номенклатура as Товар with (nolock) on Товар.id = Рег.Товар
    order by
    Товар.descr, Рег.Период
    #Список... Передается в запрос через метод "УложитьСписокОбъектов".
    :НачДата... Передается в запрос через метод "УстановитьТекстовыйПараметр".
     
  4. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
  5. Gluk8888

    Gluk8888 Гость

    Посмотреть вложение 1CSQL.chm - Очень удобный FAQ по работе 1С+SQL. Содержит в себе множество примеров по использованию прямых запросов. Особенности работы 1С. Описание структуры таблиц 1С. Рекомендации по оптимизации и многое другое.
     
  6. jj_mail

    jj_mail Гость

    не читается файлик. или я что-то не так делаю ?
     
  7. Gluk8888

    Gluk8888 Гость

    проверено скачивается, читается.
     
  8. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Использую класс "ПрямойЗапрос".
    Код ( (Unknown Language)):
        Сообщить(ЗагрузитьВнешнююКомпоненту("1CPP.dll"));
    Сообщить(ЗагрузитьВнешнююКомпоненту("1sqlite.dll"));
    Запрос = СоздатьОбъект("ПрямойЗапрос");
    ТекстЗапроса = "ВЫБРАТЬ
    |$Пров.ПервичныйДокумент КАК ПервичныйДокумент,
    |$Пров.Дата КАК ДатаОперации,
    |$Пров.ТекущийДокумент КАК [Документ $Документ],
    |$Пров.СчетДт КАК [СчДт $Счет.Основной],
    |$Пров.СчетКт КАК [СчКт $Счет.Основной],
    |$Пров.СубконтоДт1 КАК [СубкДт1 $Справочник.Контрагенты],
    |$Пров.СубконтоКт1 КАК [СубкКт1 $Справочник.Контрагенты],
    |$Пров.СубконтоДт2 КАК СубкДт2,
    |$Пров.СубконтоКт2 КАК СубкКт2,
    |$Пров.Сумма КАК Сумма,
    |$Пров.ВидСубконтоДт1 КАК [СубкДт1_вид $ВидСубконто],
    |$Пров.ВидСубконтоКт1 КАК [СубкКт1_вид $ВидСубконто]
    |ИЗ Проводки КАК Пров
    |ГДЕ ($Пров.Дата <= :КонДата)И($Пров.Дата >= :НачДата)И
    |(($Пров.СубконтоДт1 = :Контрагент)ИЛИ($Пров.СубконтоКт1 = :Контрагент))";
    Запрос.УстановитьТекстовыйПараметр("КонДата",КонДата);
    Запрос.УстановитьТекстовыйПараметр("НачДата",НачДата);
    Запрос.УстановитьТекстовыйПараметр("Контрагент",Контрагент);
    Опер = Запрос.Выполнить(,ТекстЗапроса);
    Без условия по субконто работает. Когда ставлю условие - возвращает пустую таблицу.
    |$Пров.СубконтоДт1 КАК [СубкДт1 $Субконто], - так тоже пробовал.
     
  9. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    Запрос.УстановитьТекстовыйПараметр13() попробуй - там тип не определен и айдишник получается 13 символов, а просто установитьтекстовыйпараметр() выдает 9-ти символьный.

    Если не прокатит - тогда полный 13 символьный айдишник ваять вручную - у меня где-то функция валялась, если надо - скину.

    еще вариант - ((Right($Пров.СубконтоДт1,9) = :Контрагент)ИЛИ(Right($Пров.СубконтоКт1,9) = :Контрагент)) - но тут можно обжечься, а для проверки сойдет.

    Плюс рекомендую выводить отладку, и смотреть в что же он на скуль отправляет, а уже в скуле поиграться с кверри аналайзем для полноты понимания косяка.
     
  10. Gluk8888

    Gluk8888 Гость

    еще вариант: $Пров.СубконтоДт1 = '" + Meta.ЗначениеВДлиннуюСтрокуБД(Контрагент) + "', где Meta = СоздатьОбъект("MetaDataWork");
    а в представлении необходимо типизировать немного по другому: right($Пров.СубконтоДт1,9) КАК [СубкДт1 $Справочник.Контрагенты]
     
  11. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    Я с классом "прямойзапрос" не работал, но для рекордсета именно так.
     
  12. Gluk8888

    Gluk8888 Гость

    Класс "ПрямойЗапрос" является оберткой и типизировать тоже нужно, по крайней мере в документации обратного утверждения я не нашел :ya_lamo:
     
  13. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Всем спасибо. Сейчас не до этого запроса, вернусь в тему позже.
    Сконвертировал базу в SQL, получил запрос, который корректно работает в SQL и некорректно в DBF. Отпишусь позже.
     
  14. Гость

    Надеюсь вопрос в тему, тема 100% поднималась, но вот уже второй день ищу не могу найти ничего внятного.
    Поиск в номенклатуре, в подборе 1с очень медленный, можно его как то ускорить?
    В номенклатуре около 10 000 позиций, что не очень много.
    На поиск 1й позиции даже по коду уходит 10-30 сек, на компе с базой около 2-5.
    База просто расшарена.

    Конфигурации компов:
    С базой - 4га оперативы, 2х ядерный атлоша.
    Остальные - 2га оперативы, 2х ядерные атлоны.

    Сеть через роутер, не по WiFi.
    1c 8.2 УТ
    Заранее благодарен всем отозвавшимся.
     
  15. Gluk8888

    Gluk8888 Гость

    1. Тема совсем не по теме данного топика :) а) в топике подразумеваются ввиду прямые запросы к базам 7.7. б) у вас вопрос производительности в целом.
    2. По вашему вопросу наверно лучше создать новый топик.
    3. Попробовать описать более четко как развернута информационная система.
    к примеру:

    1С 8.2 - (версия платформы) УТ (версия)
    Формат базы данных (SQL, PostgreeSQL или еще как), размер базы данных
    Сервер Базы данных конфигурация (ОЗУ, Процы, дисковая подсистема)
    Сервер Приложения 1С (если есть)
    Клиентские машины
    Количество одновременно работающих пользователей.

    Как-то так.
     
  16. Гость

    Добрый день. Надеюсь топик еще жив. Вопрос: как получить остатток по всем фирмам в столбце номенклатуры? В типовой конфигурации делает это очччень медленно.
     
  17. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    остаток чего и откуда брать? что за столбцы? какая конфа? платформа какая? вывести надо во что?
     
  18. Гость

    1С Предприятие 7.7 ТиС (немного переписанная под собственные нужды) В справочнике номенклатуры нужно получить остаток товаров на ТА по всем фирмам по всем складам и вывести в справочнике номенклатуры в каждой строке. Насколько я понимаю можно получать остаток по каждой строке отдельно в запросе, а можно как-то через Табличное Поле получить сразу по всем. Как лучше сделать? Главное чтобы быстрее работало.
     
  19. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    Ну так сделайте при открытии ТЗ с остатками, а в формуле для поля пропишите формулу поиска по этой ТЗ. Тут прямой запрос не обязателен. У меня на 150000 позициях номенклатуры было все ок.
     
  20. Гость

    Сейчас сделано вот так:
    ОстатокФирма=РегОст.СводныйОстаток(СпФирм.ТекущийЭлемент(),ТекущийЭлемент(),,,"Количество");
    Работает очень медленно. Просто жутко медленно. В базе сейчас 140 000 наименований. Одновременно работают порядка 50 пользователей. Компания розничной торговли, соотвественно все пользователи как раз-таки и сидят именно в номенклатуре. Поэтому и хотел переделать на прямой запрос.
     
Загрузка...

Поделиться этой страницей