Где в SQL Server и PostgreSQL лежит нужная таблица базы 1С

· 10 мин

Содержание

Чтобы найти таблицу 1С в SQL, вызовите в базе метод ПолучитьСтруктуруХраненияБазыДанных(): он вернёт соответствие «объект метаданных → таблица СУБД», например Справочник.Номенклатура → _Reference42. Имена в SQL-сервере обезличены, и угадать по ним, где какой справочник, нельзя. Поэтому сначала берут карту из самой 1С, а потом уже пишут запрос в SQL Server Management Studio или psql.

Если войти в 1С нельзя, остаются обходные пути: поиск по числу строк, по значению в поле _Description, по GUID ссылки или трассировка запросов, которые платформа шлёт в СУБД. Для 1С 7.7 карта лежит в файле словаря рядом с базой. Ниже — каждый способ со скриптами.

Чем хранение данных в 1С 7.7 отличается от 8.x

Обе версии кладут данные в обычные таблицы СУБД, но называют их по-разному.

Что сравниваем1С 7.7 (SQL-версия)1С 8.x
СУБДтолько MS SQL ServerMS SQL Server, PostgreSQL, IBM Db2, Oracle, файловый вариант
Имя таблицы справочникаSC84_Reference42
Имя поля-реквизитаSP85_Fld1234
Где карта имёнфайл словаря 1Cv7.DDS в каталоге базывнутри базы, читается методом платформы
Ссылка на объектID — строка из 9 символов_IDRRef — 16 байт

Номера в именах не совпадают между базами. _Reference42 в одной базе — «Номенклатура», в другой — «Контрагенты». Скрипт, написанный «под номер», к чужой базе не переносится.

Номера таблиц и полей могут смениться после загрузки .dt, удаления и повторного создания объекта или реквизита. Не зашивайте _Fld1234 в отчёты навсегда — храните карту и обновляйте её после изменений конфигурации.

Как искать таблицы в SQL-базе 1С 7.7

В 7.7 каждая таблица получает префикс по виду объекта и числовой идентификатор:

  • 📁 SC<N> — справочники;
  • 📄 DH<N> — шапки документов, DT<N> — их табличные части;
  • 📊 RA<N> — движения регистров, RG<N> — итоги регистров;
  • 📒 _1SJOURN — общий журнал документов ;
  • 🔧 _1SCONST — значения констант и периодических реквизитов.

Поля реквизитов называются SP<N>. Служебные колонки справочника читаются без словаря: ID, CODE, DESCR, PARENTID, ISMARK, ISFOLDER.

Карту имён даёт файл 1Cv7.DDS в каталоге информационной базы. Это текстовый файл: откройте его копию в любом редакторе и найдите по названию объекта. Рядом с названием «Номенклатура» будет стоять имя таблицы вида SC84, ниже — строки полей SP… с названиями реквизитов.

💡 Не открывайте сам 1Cv7.DDS на запись. Скопируйте его и работайте с копией: испорченный словарь не даст базе запуститься.

Карта хранения в 1С 8.x: метод вместо служебной таблицы

В 8.x человекочитаемой таблицы с метаданными нет. Описание конфигурации лежит в служебной таблице Config, а соответствие имён — в таблице Params (запись DBNames). Обе хранят данные в сжатом двоичном виде, прочитать их запросом SELECT не получится.

Правильный путь — спросить платформу. Метод глобального контекста ПолучитьСтруктуруХраненияБазыДанных(ОбъектыМетаданных, ИменаБазыДанных) возвращает таблицу значений с колонками:

  • ИмяТаблицыХранения — имя таблицы в СУБД;
  • Метаданные — полное имя объекта, например Справочник.Номенклатура;
  • Назначение — роль таблицы: основная, табличная часть, итоги и т. д.;
  • Поля — вложенная таблица: ИмяПоля (реквизит) и ИмяПоляХранения (колонка в СУБД).

Второй параметр Истина возвращает имена в том виде, как их видит СУБД. Для PostgreSQL это важно: там все имена в нижнем регистре.

Код для внешней обработки

Создайте внешнюю обработку в Конфигураторе, добавьте форму и вызовите на сервере такую процедуру:

&НаСервереБезКонтекста
Процедура ПоказатьТаблицыНоменклатуры()
	Объекты = Новый Массив;
	Объекты.Добавить(Метаданные.Справочники.Номенклатура);
	Структура = ПолучитьСтруктуруХраненияБазыДанных(Объекты, Истина);
	Для Каждого Строка Из Структура Цикл
		Сообщить(СтрШаблон("%1 | %2 | %3", Строка.Метаданные, Строка.Назначение, Строка.ИмяТаблицыХранения));
		Для Каждого Поле Из Строка.Поля Цикл
			Сообщить(СтрШаблон("    %1 = %2", Поле.ИмяПоля, Поле.ИмяПоляХранения));
		КонецЦикла;
	КонецЦикла;
КонецПроцедуры

Без первого параметра метод вернёт всю базу — это тысячи строк. Для разовой задачи передавайте только нужные объекты.

Как расшифровать имя таблицы без 1С

Префикс сразу подсказывает вид объекта:

ПрефиксЧто хранит
_Reference<N>справочник
_Document<N>шапка документа
_Document<N>_VT<M>табличная часть документа
_AccumRg<N> / _AccumRgT<N>движения / итоги регистра накопления
_InfoRg<N>регистр сведений
_AccRg<N>регистр бухгалтерии
_Acc<N>план счетов
_Chrc<N>план видов характеристик
_Enum<N>перечисление
_Const<N>константа
_Node<N>узлы плана обмена
_ReferenceChngR<N>, _DocumentChngR<N>регистрация изменений для обмена

Типовые колонки: _IDRRef — ссылка, _Marked — пометка удаления, _Code, _Description, _ParentIDRRef — родитель, _LineNo<N> — номер строки табличной части.

Поиск таблиц в MS SQL Server и PostgreSQL

Карта из 1С есть не всегда: база не открывается, нет пароля, нужно разобраться за пять минут. Тогда ищите по косвенным признакам.

По числу строк

Самая большая таблица в учётной базе почти всегда регистр. Список с количеством строк в MS SQL Server:

SELECT t.name, SUM(p.rows) AS rows_cnt
FROM sys.tables t
JOIN sys.partitions p ON p.object_id = t.object_id AND p.index_id IN (0, 1)
GROUP BY t.name
ORDER BY rows_cnt DESC;

То же в PostgreSQL:

SELECT relname, n_live_tup,
       pg_size_pretty(pg_total_relation_size(relid)) AS size
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC
LIMIT 30;

n_live_tup — оценка по статистике, а не точный COUNT(*). Для поиска «самых тяжёлых» её хватает.

По значению наименования

Знаете, что в справочнике есть элемент «Ромашка»? Найдите все таблицы, где он лежит в _Description. Скрипт для MS SQL Server:

DECLARE @text nvarchar(100) = N'Ромашка';
DECLARE @sql nvarchar(max) = N'';

SELECT @sql = @sql + N' UNION ALL SELECT ''' + t.name + N''' AS tbl, COUNT(*) AS cnt FROM dbo.'
     + QUOTENAME(t.name) + N' WHERE _Description LIKE N''%' + @text + N'%'' HAVING COUNT(*) > 0'
FROM sys.tables t
JOIN sys.columns c ON c.object_id = t.object_id
WHERE c.name = '_Description';

SET @sql = STUFF(@sql, 1, 11, N'');
EXEC sp_executesql @sql;

Скрипт читает каждую таблицу целиком. На базе в сотни гигабайт запускайте его вне рабочего времени.

В PostgreSQL проще отфильтровать список кандидатов, а затем проверить их по одному:

SELECT table_name
FROM information_schema.columns
WHERE table_schema = 'public' AND column_name = '_description';

По GUID ссылки

В 1С уникальный идентификатор показывается строкой aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee. В _IDRRef те же байты записаны в другом порядке: dddd + eeeeeeeeeeee + cccc + bbbb + aaaaaaaa. Без перестановки запрос ничего не найдёт.

MS SQL Server:

DECLARE @g char(36) = 'b1d8c4a2-3f5e-11ee-8c90-0242ac120002';
DECLARE @ref binary(16) = CONVERT(binary(16), '0x'
  + SUBSTRING(@g, 20, 4) + SUBSTRING(@g, 25, 12)
  + SUBSTRING(@g, 15, 4) + SUBSTRING(@g, 10, 4) + SUBSTRING(@g, 1, 8), 1);
SELECT * FROM dbo._Reference42 WHERE _IDRRef = @ref;

PostgreSQL:

SELECT r.*
FROM _reference42 r,
     (SELECT 'b1d8c4a2-3f5e-11ee-8c90-0242ac120002'::text AS g) s
WHERE r._idrref = decode(
  substr(s.g, 20, 4) || substr(s.g, 25, 12) || substr(s.g, 15, 4)
  || substr(s.g, 10, 4) || substr(s.g, 1, 8), 'hex');

Чем отличаются две СУБД

ПризнакMS SQL ServerPostgreSQL
Регистр имён_Reference42, _Fld1234_reference42, _fld1234
Тип ссылкиbinary(16)bytea
Строкиnvarchar, ncharmvarchar, mchar — типы из сборки PostgreSQL для 1С
Схемаdbopublic

Из-за типов mvarchar и mchar часть стандартных функций PostgreSQL работает с такими полями иначе. Если сравнение строк ведёт себя странно, приведите поле к text.

Трассировка: что читает форма

Приём, о котором часто забывают: откройте нужную форму в 1С и посмотрите, какие запросы ушли в СУБД. В MS SQL Server это расширенные события (Extended Events) или SQL Server Profiler с фильтром по имени базы. Для любой СУБД подходит технологический журнал 1С с событием DBMSSQL — в нём виден текст SQL-запроса и имена таблиц.

💡 Фильтруйте трассировку по своему пользователю или сеансу. Иначе в рабочей базе вы утонете в чужих запросах за секунды.

Как разобрать структуру таблицы и найти нужное поле

Нашли таблицу — дальше нужны колонки. В MS SQL Server:

SELECT c.name, ty.name AS type_name, c.max_length
FROM sys.columns c
JOIN sys.types ty ON ty.user_type_id = c.user_type_id
WHERE c.object_id = OBJECT_ID('dbo._Reference42')
ORDER BY c.column_id;

В PostgreSQL — \d _reference42 в psql или запрос:

SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = '_reference42'
ORDER BY ordinal_position;

Как читать суффиксы полей

  • 🔗 _Fld1234RRef — ссылка на объект одного типа (16 байт).
  • 🧩 Реквизит составного типа раскладывается на несколько колонок: _Fld1234_TYPE (какой тип лежит), _Fld1234_N (число), _Fld1234_S (строка), _Fld1234_T (дата), _Fld1234_L (булево), _Fld1234_RTRef (номер таблицы ссылки) и _Fld1234_RRRef (сама ссылка).
  • 🔢 _LineNo<N> — номер строки в табличной части.
  • 🗂️ _Document<N>_IDRRef в таблице _VT — ссылка на шапку документа.

Так одна колонка _Fld1234RRef в таблице документа выводит на справочник: берёте её значение и ищете по _IDRRef в кандидатах _Reference….

Что у вас есть для поиска таблицы?

Автоматизация поиска через командную строку

Когда карта нужна регулярно — например, для отчётов в BI, — выгружайте её в файл по расписанию.

Выгрузка карты из 1С в CSV

Процедура в модуле внешней обработки:

Процедура ВыгрузитьСтруктуру(ИмяФайла) Экспорт
	Структура = ПолучитьСтруктуруХраненияБазыДанных(, Истина);
	Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);
	Запись.ЗаписатьСтроку("Объект;Назначение;Таблица;Реквизит;Поле");
	Для Каждого Строка Из Структура Цикл
		Для Каждого Поле Из Строка.Поля Цикл
			Запись.ЗаписатьСтроку(СтрШаблон("%1;%2;%3;%4;%5",
				Строка.Метаданные, Строка.Назначение, Строка.ИмяТаблицыХранения,
				Поле.ИмяПоля, Поле.ИмяПоляХранения));
		КонецЦикла;
	КонецЦикла;
	Запись.Закрыть();
КонецПроцедуры

Запустить обработку без участия человека можно параметром /Execute:

"C:\Program Files\1cv8\8.3.24.1548\bin\1cv8.exe" ENTERPRISE /S "srv1c\buh" /N "Администратор" /P "пароль" /Execute "C:\tools\dump_structure.epf"

Подставьте свою версию платформы, сервер и базу. Пароль в bat-файле храните только на сервере с ограниченным доступом.

Запросы из консоли СУБД

Для MS SQL Server — утилита sqlcmd, результат сразу в файл:

sqlcmd -S srvsql -d buh -E -Q "SELECT name FROM sys.tables WHERE name LIKE '_Reference%' ORDER BY name" -o C:\tmp\refs.txt

Для PostgreSQL — psql:

psql -h srvpg -U postgres -d buh -c "\dt _reference*"

Выгрузку из 1С и список таблиц из СУБД удобно сводить в одну таблицу: так видно, какие таблицы появились после обновления конфигурации.

Ошибки при работе с таблицами 1С в SQL и как не навредить базе

  • ❌ Запись в таблицы напрямую. UPDATE или DELETE в обход платформы ломает итоги регистров, ссылочную целостность и версии объектов (_Version). 1С не узнает об изменении, обмен не зарегистрирует его. Пишите в SQL только чтение.
  • ❌ Работа под sa или postgres. Для аналитики заведите отдельного пользователя СУБД с правом только на чтение нужной базы.
  • ❌ Тяжёлые запросы в рабочее время. Перебор всех таблиц и SELECT * по регистру на десятки миллионов строк нагружают сервер и тормозят пользователей. Ставьте TOP или LIMIT, запускайте вечером.
  • ❌ WITH (NOLOCK) без понимания. Он снимает блокировки, но может вернуть незафиксированные или задвоенные строки. Для разового поиска допустимо, для отчёта с суммами — нет.
  • ❌ Чтение _AccumRgT как готовых остатков. Таблица итогов хранит данные по периодам и разделителям; при выключенных итогах она неактуальна. Остатки надёжнее брать запросом из 1С.
  • ❌ Поиск по _Description в PostgreSQL через LIKE с кириллицей. Регистр букв и тип mvarchar дают неожиданные результаты — используйте ILIKE и приведение к text.

Если всё же нужно что-то поправить в данных через SQL — сначала полная резервная копия базы и согласование с ответственным за 1С. Исправление делают на копии, проверяют в 1С и только потом повторяют в рабочей базе в нерабочее время, когда пользователи вышли.

Работает ли ПолучитьСтруктуруХраненияБазыДанных в файловой базе?
Да. Метод возвращает имена таблиц и для файлового варианта, но читать файл 1Cv8.1CD средствами SQL нельзя — для этого базу сначала переносят на SQL-сервер.
Почему в PostgreSQL запрос к _Reference42 пишет, что таблицы нет?
PostgreSQL хранит имена в нижнем регистре. Пишите _reference42 или передайте второй параметр Истина в метод 1С — он вернёт имена в нужном регистре.
Можно ли подключить Power BI или Excel прямо к таблицам 1С?
Технически да, через пользователя с правом чтения. Но расшифровку _Fld и составных типов придётся поддерживать вручную после каждого обновления — для постоянной аналитики удобнее выгрузка из 1С или OData.
Как понять, на какую таблицу указывает _Fld1234_RTRef?
Это номер из имени таблицы: значение 42 означает _Reference42. В MS SQL Server он хранится как 4 байта в шестнадцатеричном виде, переведите его в десятичное число.
Меняются ли имена таблиц после обновления типовой конфигурации?
У существующих объектов обычно нет. Новые объекты и реквизиты получают новые номера, удалённые исчезают. После обновления с реструктуризацией перевыгрузите карту.