При выполнении прямых запросов к базе данных 1С на СУБД MS SQL Server или при работе через механизм Внешние источники данных разработчики часто сталкиваются с невозможностью использовать привычный оператор языка запросов 1С ССЫЛКА. Рассмотрим, как устроено хранение ссылочных типов на уровне СУБД и какими способами можно реализовать аналог такой проверки.
В таблицах накопления и сведений платформы 1С:Предприятие составное поле регистратора разделяется на две основные колонки:
_RecorderRRef — непосредственно GUID (уникальный идентификатор) конкретного документа-регистратора (длина 16 байт)._RecorderTRef — тип ссылки документа-регистратора (длина 4 байта, тип данных binary(4)).Поле _RecorderTRef хранит внутренний числовой идентификатор объекта метаданных в шестнадцатеричном виде. Например, если в структуре хранения базы данных таблица документа «Поступление товаров из переработки» имеет имя _Document143, то числовой идентификатор этого типа равен 143.
Чтобы узнать имя таблицы нужного документа в СУБД, выполним встроенную функцию 1С:
СтруктураБазы = ПолучитьСтруктуруХраненияБазыДанных();
Число 143 в 16-ричной системе счисления соответствует значению 0x0000008F.
Если мы составляем прямой запрос к базе данных MS SQL (например, через COM-объект ADODB.Connection), то отфильтровать записи по типу документа можно несколькими способами.
1. Фильтрация по шестнадцатеричному литералу:
SELECT *
FROM _AccumRg1234 -- Таблица регистра
WHERE _RecorderTRef = 0x0000008F
2. Явное приведение целого числа к типу binary(4):
SELECT *
FROM _AccumRg1234
WHERE _RecorderTRef = CAST(143 AS binary(4))
Важное замечание по производительности: не рекомендуется использовать выражение WHERE CAST(_RecorderTRef AS int) = 143. Оборачивание колонки таблицы в функцию CAST лишает MS SQL Server возможности эффективно использовать индекс по полю регистратора (происходит Index Scan вместо Index Seek).
Когда таблица MS SQL подключается к 1С через объект метаданных Внешние источники данных, платформа воспринимает её как стороннюю таблицу СУБД. В этом случае оператор ССЫЛКА недоступен, а язык запросов 1С к внешним источникам не позволяет использовать шестнадцатеричные литералы вида 0x... или встроенные функции T-SQL.
Разберем решения этой проблемы:
Создадим на сервере баз данных представление над нужной таблицей регистра, вынеся приведение типа в отдельное виртуальное поле:
CREATE VIEW dbo.v_TovaryNaSkladah AS
SELECT
*,
CAST(_RecorderTRef AS int) AS RecorderTRefInt
FROM _AccumRg1234
После этого подключим представление v_TovaryNaSkladah во внешние источники данных 1С и сможем писать простой запрос:
ВЫБРАТЬ
Таблица.Количество
ИЗ
ВнешнийИсточникДанных.ИмяИсточника.Таблица.v_TovaryNaSkladah КАК Таблица
ГДЕ
Таблица.RecorderTRefInt = 143
Если задача позволяет отказаться от стандартного объекта «Внешний источник данных», организуем подключение к MS SQL через ADODB.Connection и передадим T-SQL запрос с явным условным оператором WHERE _RecorderTRef = 0x0000008F.
Проанализируем риски использования зашитых идентификаторов типов метаданных:
.dt, при сравнении и объединении конфигураций или переносе базы на другой контур этот ID может измениться. Жесткая фиксация чисел в коде или запросах рискованна.