О чем эта статья
Статья описывает физическую реализацию виртуальной таблицы остатков конфигурации, работающей в клиент-серверном режиме работы на примере использования СУБД MS SQL Server.
Применимость
В статье рассматривается платформа «1С:Предприятие» редакции 8.3.5.1383. В актуальной версии платформы возможны некоторые изменения в тексте, описанного в материале, запроса T-SQL, выполняемого на стороне сервера СУБД.
Устройство виртуальной таблицы остатков
Рассмотрим, в какой запрос к СУБД трансформируется запрос с использованием виртуальной таблицы остатков регистра накопления. Для примера будет рассматриваться следующий текст запроса:
ТоварныеЗапасыОстатки.Товар,
ТоварныеЗапасыОстатки.Склад,
ТоварныеЗапасыОстатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварныеЗапасы.Остатки(&Дата, Склад = &Склад) КАК
ТоварныеЗапасыОстатки
Сначала при помощи метода глобального контекста ПолучитьСтруктуруХраненияБазыДанных() получим список таблиц базы данных, в которых хранятся данные регистра накопления «ТоварныеЗапасы»:
Состав полей основной таблицы регистра накопления и таблицы итогов приведен ниже:
Хранение итогов для данного регистра настроено в режиме «1С:Предприятие 8» следующим образом:
Параметры в рассматриваемом запросе заполним следующим образом:
Платформа преобразует текст запроса в следующий запрос, который и будет выполнен на сервере СУБД:
Q_000_T_001.Fld82,
Q_000_T_001.Fld83,
Q_000_T_001.Fld84Balance
FROM
(SELECTFld82,
Fld83,
SUM(Fld84Balance)ASFld84Balance
FROM
(SELECTFld82,
Fld83,
SUM(Fld84)ASFld84Balance
FROMAccumRgT85
WHEREPeriod=DATETIME(3999,11,1)
AND((Fld83=9:a9b000055d49b45e11db8b8bee7616e1))
AND(Fld84<>0)AND(Fld84<>0)
GROUPBYFld82,Fld83
HAVINGFld84Balance<>0
UNIONALL
SELECTFld82,
Fld83,
SUM(CASEWHENRecordKind=0THEN–Fld84ELSEFld84END)ASFld84Balance
FROMAccumRg81
WHEREPeriod>=DATETIME(2012,9,1)
ANDPeriod<DATETIME(3999,11,1)
ANDActive
AND((Fld83=9:a9b000055d49b45e11db8b8bee7616e1))
GROUPBYFld82,Fld83
HAVINGFld84Balance<>0)T
GROUPBYFld82,Fld83
HAVINGFld84Balance<>0)Q_000_T_001
Разберем подробнее полученный запрос.
Сначала при помощи первого запроса, входящего в объединение, выбираются данные из итоговой таблицы AccumRgT85. Итоги получаются на дату хранения текущих итогов (01.11.3999), дополнительно накладывается условие на поле Склад (поскольку такое условие использовалось в параметрах виртуальной таблицы). Дополнительно выполняется проверка на отсутствие в результате строк с нулевыми остатками.
Обратите внимание, что производится группировка по выбранным в тексте запроса измерениям. Именно поэтому не требуется в тексте на языке запросов «1С:Предприятие» дополнительно выполнять группировку по измерениям.
Во втором запросе объединения используется таблица движений регистра AccumRg81. В зависимости от вида движения (если RecordKind равно 0, то это Приход, в противном случае – Расход) проставляется знак в выражении. Платформа выбирает данные за период с даты, указанной в качестве параметра виртуальной таблицы, по дату хранения текущих итогов (01.11.3999).
Кроме этого отбираются только активные записи, поле Склад должно быть равно заданному значению. Как и в первом запросе объединения, здесь также производится группировка по выбранным измерениям и отбрасываются записи с нулевыми значениями ресурсов.
Если используется СУБД MS SQL Server и для базы данных установлено смещение дат 2000, то все даты будут храниться с указанным смещением, т.е. вместо 01.11.3999 Вы увидите 01.11.5999.
Если для регистра накопления отключить текущие итоги, то платформа сначала получит последние итоги, рассчитанные на дату, раньше указанной в параметре Период виртуальной таблицы.
Затем аналогично эти данные будут дополнены из таблицы движений, но только за период с даты последних итогов по период виртуальной таблицы.
Q_000_T_001.Fld82,
Q_000_T_001.Fld83,
Q_000_T_001.Fld84Balance
FROM
(SELECTFld82,
Fld83,
SUM(Fld84Balance)ASFld84Balance
FROM
(SELECTFld82,
Fld83,
SUM(Fld84)ASFld84Balance
FROMAccumRgT85
WHEREPeriod=DATETIME(2012,4,1)
AND((Fld83=9:a9b000055d49b45e11db8b8bee7616e1))
AND(Fld84<>0)
AND(Fld84<>0)
GROUPBYFld82,Fld83
HAVINGFld84Balance<>0
UNIONALL
SELECTFld82,
Fld83,
SUM(CASEWHENRecordKind=0THENFld84ELSE–Fld84END)ASFld84Balance
FROMAccumRg81
WHEREPeriod>=DATETIME(2012,4,1)
ANDPeriod<DATETIME(2012,9,1)
ANDActive
AND((Fld83=9:a9b000055d49b45e11db8b8bee7616e1))
GROUPBYFld82,Fld83
HAVINGFld84Balance<>0)T
GROUPBYFld82,Fld83
HAVINGFld84Balance<>0)Q_000_T_001
Обратите внимание на следующее условие в тексте запроса:
То есть движения с периодом, равным параметру виртуальной таблицы, не будут учитываться при получении остатков. Ранее упоминалось, что таблица остатков строится на начало секунды, не включая указанный период.
Таким образом, таблица итогов регистра накопления позволяет оптимизировать получение остатков.
PDF-версия статьи для участников группы ВКонтакте
Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.
Если Вы еще не вступили в группу – сделайте это сейчас и в блоке ниже (на этой странице) появятся ссылка на скачивание материалов.
Статья в PDF-формате
Вы можете скачать эту статью в формате PDF: Курсы-по-1С.рф – Материалы из курса по запросам – Устройство виртуальной таблицы остатков.pdf
P.S.
Понимать, как работают запросы и уметь их строить - обязательный навык для всех, кто дорабатывает и внедряет 1С.
После курса Вы сможете:
- Строить сложные запросы с несколькими источниками данных
- Уверенно задействовать вложенные запросы и временные таблицы
- Использовать встроенный язык для обработки результатов запроса
- Учитывать особенности соединений и объединений нескольких таблиц.
- Разрабатывать запросы на уровне задач Аттестации 1С:Специалист по платформе.
А как получить это запрос, который передаётся в SQL?
Получить такой запрос можно из технологического журнала, который формирует платформа. Также существуют консоли запросов, которые умеют показывать запрос, передаваемый на СУБД. Например, консоль запросов для управляемого приложения с сайта ИТС.
Текст запроса из SQL абсолютно не читаем.
Просто набор символов и абракадабра.
Естественно, управляющие конструкции запроса прочитать можно, но и только.
Мне, например, чтобы понять этот запрос приходится все названия полей и таблиц “переводить” на русский, заменяя их привычными русскоязычными названиями полей из конфигуратора.
Только после этого смысл и механика запроса становятся читаемыми.
ИТ-шники “от рождения” конечно поймут запрос “с листа”
это мое личное мнение -)))
Для того и созданы виртуальные таблицы, чтобы облегчить жизнь :))
Тем не менее, полезно знать, что происходит “внутри” платформы.