Когда речь заходит о работе с базами данных в 1С:Предприятие, разработчики неизбежно сталкиваются с выбором: использовать встроенный язык запросов платформы или обращаться напрямую к SQL-серверу через прямые запросы. На первый взгляд оба подхода решают одну задачу — извлечение и модификацию данных, но на практике разница между ними приводит к радикально разным результатам по производительности, безопасности и гибкости.

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

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

1. Синтаксис: почему 1С-запросы выглядят иначе

Первое, что бросается в глаза — это непривычный синтаксис языка запросов 1С. В то время как стандартный SQL оперирует ключевыми словами вроде SELECT, FROM, WHERE, в 1С используется более"разговорный" стиль с конструкциями типа ВЫБРАТЬ, ИЗ, ГДЕ. Это не просто перевод на русский — за этим стоят принципиальные различия в логике работы.

Например, в классическом SQL для выборки данных с условием вы напишете:

SELECT Name, Price

FROM Products

WHERE CategoryID = 5 AND Price > 1000

ORDER BY Name

В 1С этот же запрос будет выглядеть так:

ВЫБРАТЬ

Наименование КАК Name,

Цена КАК Price

ИЗ

Справочник.Номенклатура КАК Products

ГДЕ

Категория = &Категория

И Цена > 1000

УПОРЯДОЧИТЬ ПО

Наименование

  • 📌 Ключевые слова на русском — все операторы переводятся, что может сбивать с толку новичков, привыкших к английскому синтаксису.
  • 🔄 Иная логика псевдонимов — в 1С псевдонимы указываются явно через КАК, а не неявно после имени поля.
  • 💡 Параметры с амперсандом — вместо подстановки значений напрямую (как в SQL) в 1С используются именованные параметры с префиксом &.
⚠️ Внимание: В 1С нельзя использовать SELECT * — платформа требует явного перечисления всех полей. Это защищает от ошибок при изменении структуры таблиц, но усложняет написание универсальных запросов.

2. Работа с типами данных: где 1С проигрывает SQL

Одна из самых болезненных разниц — это поддержка типов данных. Стандартный SQL оперирует универсальными типами (INT, VARCHAR, DATETIME), которые одинаково работают в MySQL, PostgreSQL или MS SQL Server. В 1С же типы привязаны к метаданным конфигурации, что накладывает серьёзные ограничения.

Например, в SQL вы можете легко конвертировать строки в даты:

SELECT CONVERT(DATE,'2026-12-31', 120) AS FormattedDate

В 1С для этого потребуется использовать функцию ДАТАЗНАЧ, которая работает только с форматом ДД.ММ.ГГГГ:

ВЫБРАТЬ

ДАТАЗНАЧ("31.12.2026") КАК Дата

Тип данных SQL Комментарий
Дата/время DATETIME, TIMESTAMP Дата, МоментВремени В 1С нет отдельного типа для времени без даты
Строка VARCHAR(MAX), TEXT Строка(255), НеограниченнаяСтрока В 1С длина строки по умолчанию ограничена 255 символами
Булево значение BIT, BOOLEAN Булево В SQL TRUE/FALSE, в 1С — Истина/Ложь
NULL NULL NULL (но ведёт себя иначе) В 1С NULL не равно пустой строке или нулю
⚠️ Внимание: В 1С нельзя использовать CAST или CONVERT для произвольных преобразований типов. Например, попытка привести число к строке через СТРОКА(Число) может дать неожиданный результат с разделителями тысяч.
📊 Какой синтаксис запросов вам удобнее?
Классический SQL (SELECT FROM)
1С (ВЫБРАТЬ ИЗ)
Оба в зависимости от задачи
Не знаю, ещё не работал

3. Производительность: почему прямые SQL-запросы быстрее

Если говорить о скорости выполнения, то прямые SQL-запросы почти всегда выигрывают у встроенного языка 1С. Дело в том, что платформа 1С добавляет свой слой обработки поверх SQL, что приводит к накладным расходам. Например, простой запрос выборки из 10 000 строк в 1С может выполняться в 3-5 раз медленнее, чем аналогичный запрос напрямую к базе.

Разница становится особенно заметна при:

  • 📊 Агрегации больших данныхGROUP BY в 1С работает медленнее из-за дополнительной обработки.
  • 🔍 Сложных JOIN’ах — платформа 1С может оптимизировать соединения неэффективно.
  • 📈 Массовых обновленияхОБНОВИТЬ в 1С часто блокирует таблицы дольше, чем прямой UPDATE.

Пример: обновление цен в 100 000 товарах.

В 1С:

ОБНОВИТЬ Справочник.Номенклатура

УСТАНОВИТЬ Цена = Цена * 1.1

ГДЕ Категория = &Категория

Прямой SQL (MS SQL Server):

UPDATE [dbo].[_Reference16] -- Номенклатура

SET [Price] = [Price] * 1.1

WHERE [CategoryRef] = @Category

Последний вариант выполнится в разы быстрее, особенно если на поле CategoryRef есть индекс.

💡

Перед массовыми операциями в 1С всегда проверяйте наличие индексов на полях, используемых в условиях ГДЕ. Отсутствие индекса может сделать запрос в 100 раз медленнее!

4. Безопасность: почему 1С ограничивает SQL

Платформа 1С намеренно блокирует часть SQL-возможностей по соображениям безопасности и стабильности. Это защищает от ошибок новичков, но ограничивает опытных разработчиков. Вот что нельзя сделать в 1С-запросах:

  • 🚫 DROP TABLE — удаление таблиц запрещено на уровне платформы.
  • 🚫 EXEC — нельзя выполнять динамический SQL-код.
  • 🚫 TRUNCATE TABLE — вместо этого приходится использовать УДАЛИТЬ с фильтром.
  • 🚫 Создание временных таблиц — в 1С нет аналога #TempTable или CTE (Common Table Expressions).

Даже если вы используете прямые SQL-запросы через Новый Запрос с параметром ТекстЗапроса ="Ваш SQL", платформа всё равно накладывает ограничения:

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

5. Работа с иерархиями и справочниками

Одним из ключевых преимуществ языка запросов 1С является встроенная поддержка иерархических данных. В то время как в стандартном SQL для работы с деревьями приходится писать рекурсивные запросы (например, с WITH RECURSIVE в PostgreSQL), в 1С это реализовано"из коробки".

Пример: выборка всех подчинённых элементов справочника.

В 1С:

ВЫБРАТЬ

Справочник.Подразделения.Ссылка КАК Ссылка,

Справочник.Подразделения.Наименование КАК Наименование

ИЗ

Справочник.Подразделения КАК Справочник.Подразделения

ГДЕ

Справочник.Подразделения.Родитель = &Родитель

В SQL (рекурсивный запрос для MS SQL Server):

WITH RecursiveCTE AS (

SELECT ID, Name, ParentID

FROM Departments

WHERE ParentID = @ParentID

UNION ALL

SELECT d.ID, d.Name, d.ParentID

FROM Departments d

INNER JOIN RecursiveCTE r ON d.ParentID = r.ID

)

SELECT * FROM RecursiveCTE

Как видно, в 1С не нужно писать рекурсию — платформа сама обрабатывает иерархию. Однако это работает только для справочников 1С. Если вам нужно построить дерево по произвольной таблице в базе, рекурсивный SQL всё равно потребуется.

Как ускорить рекурсивные запросы в SQL?

Для больших иерархий (глубиной >10 уровней) рекурсивные CTE работают медленно. В таких случаях лучше:

1. Использовать материализованные пути (path materialization).

2. Хранить в таблице поля LeftKey и RightKey (модель вложенных множеств).

3. Применять хранимые процедуры с временными таблицами.

6. Обработка NULL и пустых значений

Ещё одно коварное отличие — это поведение NULL. В стандартном SQL NULL означает"отсутствие значения" и обрабатывается через IS NULL/IS NOT NULL. В 1С же NULL может вести себя непредсказуемо, особенно в сравнениях.

Сравните:

SQL:

SELECT * FROM Orders

WHERE CustomerID IS NULL

1С:

ВЫБРАТЬ *

ИЗ Документ.ЗаказыКлиентов КАК Заказы

ГДЕ Заказы.Клиент ЕСТЬ NULL

Но здесь начинаются подводные камни:

  • 🔴 В 1С NULL не равно пустой ссылке (Ссылка.Пустая).
  • 🔴 Сравнение Значение = NULL всегда возвращает Ложь (как и в SQL), но в 1С это часто сбивает с толку.
  • 🔴 Функции агрегации (СУММА, МАКСИМУМ) игнорируют NULL, но в 1С это не всегда очевидно.

Пример проблемы:

ВЫБРАТЬ

СУММА(ЕСЛИ(Заказы.Сумма ЕСТЬ NULL, 0, Заказы.Сумма)) КАК Итог

ИЗ

Документ.ЗаказыКлиентов КАК Заказы

В SQL этот запрос можно было бы написать проще:

SELECT SUM(COALESCE(Amount, 0)) AS Total FROM Orders

7. Интеграция с внешними системами

Если ваша задача — обмен данными с внешними системами (например, выгрузка в Excel, JSON API или другая база данных), то прямые SQL-запросы дают гораздо больше возможностей. Встроенный язык 1С ограничен форматами платформы, тогда как SQL позволяет:

  • 📤 Экспортировать данные в CSV/JSON напрямую из запроса (например, через FOR JSON PATH в MS SQL).
  • 🔗 Создавать сложные отчёты с использованием оконных функций (OVER).
  • 🔄 Синхронизировать данные между базами через MERGE или BULK INSERT.

Пример выгрузки данных в JSON:

MS SQL Server:

SELECT

DepartmentID,

Name,

(SELECT EmployeeID, Name, Position

FROM Employees

WHERE DepartmentID = Departments.ID

FOR JSON PATH) AS Employees

FROM Departments

FOR JSON PATH

1С:

Для этого придётся сначала выбрать данные, а затем вручную формировать JSON через Новый ЗаписьJSON, что менее эффективно.

⚠️ Внимание: При интеграции через прямые SQL-запросы убедитесь, что ваш пользователь базы данных имеет достаточные права. В 1С по умолчанию часто используются учётные записи с ограниченным доступом (например, v82user), которые не могут выполнять некоторые операции.
💡

Для задач интеграции с внешними системами прямые SQL-запросы почти всегда предпочтительнее встроенного языка 1С. Они дают больше контроля над форматами данных и позволяют использовать возможности СУБД (например, генерацию JSON/XML напрямую в запросе).

FAQ: Частые вопросы по 1С и SQL

Можно ли в 1С использовать оконные функции (OVER, PARTITION BY)?

Нет, встроенный язык запросов 1С не поддерживает оконные функции. Для их использования нужно писать прямые SQL-запросы (если СУБД это позволяет) или эмулировать логику через временные таблицы в 1С.

Как в 1С сделать запрос с JOIN по произвольному условию, а не только по ссылкам?

В 1С соединения (СОЕДИНИТЬ) по умолчанию работают только по ссылкам на объекты метаданных. Для произвольных условий используйте конструкцию СОЕДИНИТЬ ПО:

ВЫБРАТЬ

Заказы.Номер,

Клиенты.Наименование

ИЗ

Документ.ЗаказыКлиентов КАК Заказы

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Клиенты КАК Клиенты

ПО Заказы.КодКлиента = Клиенты.Код

Почему мой SQL-запрос работает в Management Studio, но не работает в 1С?

Эточная проблема, связанная с тем, что 1С:

  1. Подменяет имена таблиц на внутренние (например, _Reference16 вместо Номенклатура).
  2. Блокирует некоторые конструкции (например, DROP, TRUNCATE).
  3. Использует другой пользователь базы данных с ограниченными правами.

Решение: проверьте запрос через Новый Запрос(ТекстЗапроса).Выполнить и посмотрите текст ошибки. Часто помогает замена имён таблиц на реальные (их можно узнать через ИнформацияОБазеДанных).

Как ускорить медленный запрос в 1С?

Порядок действий:

  1. Проверьте, есть ли индексы на полях, используемых в ГДЕ и СОЕДИНИТЬ.
  2. Замените ВЫБРАТЬ РАЗЛИЧНЫЕ на ГРУППИРОВКА ПО — это часто ускоряет выполнение.
  3. Разбейте сложный запрос на несколько простых с использованием временных таблиц (в 1С для этого есть ВЫГРУЗИТЬ и ЗАГРУЗИТЬ).
  4. Если ничего не помогает, перепишите запрос на прямой SQL (но учитывайте ограничения 1С).
Можно ли в 1С использовать транзакции в SQL-запросах?

Технически да, но с оговорками:

  • Встроенные транзакции 1С (НачатьТранзакцию) не распространяются на прямые SQL-запросы.
  • Для SQL-транзакций нужно использовать BEGIN TRANSACTION и COMMIT прямо в тексте запроса, но 1С может прервать выполнение, если запрос займёт слишком много времени.
  • Лучший вариант — вынести сложную логику в хранимые процедуры на стороне СУБД.