Когда речь заходит о работе с базами данных в 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 | 1С | Комментарий |
|---|---|---|---|
| Дата/время | DATETIME, TIMESTAMP |
Дата, МоментВремени |
В 1С нет отдельного типа для времени без даты |
| Строка | VARCHAR(MAX), TEXT |
Строка(255), НеограниченнаяСтрока |
В 1С длина строки по умолчанию ограничена 255 символами |
| Булево значение | BIT, BOOLEAN |
Булево |
В SQL TRUE/FALSE, в 1С — Истина/Ложь |
| NULL | NULL |
NULL (но ведёт себя иначе) |
В 1С NULL не равно пустой строке или нулю |
⚠️ Внимание: В 1С нельзя использоватьCASTилиCONVERTдля произвольных преобразований типов. Например, попытка привести число к строке черезСТРОКА(Число)может дать неожиданный результат с разделителями тысяч.
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С:
- Подменяет имена таблиц на внутренние (например,
_Reference16вместоНоменклатура). - Блокирует некоторые конструкции (например,
DROP,TRUNCATE). - Использует другой пользователь базы данных с ограниченными правами.
Решение: проверьте запрос через Новый Запрос(ТекстЗапроса).Выполнить и посмотрите текст ошибки. Часто помогает замена имён таблиц на реальные (их можно узнать через ИнформацияОБазеДанных).
Как ускорить медленный запрос в 1С?
Порядок действий:
- Проверьте, есть ли индексы на полях, используемых в
ГДЕиСОЕДИНИТЬ. - Замените
ВЫБРАТЬ РАЗЛИЧНЫЕнаГРУППИРОВКА ПО— это часто ускоряет выполнение. - Разбейте сложный запрос на несколько простых с использованием временных таблиц (в 1С для этого есть
ВЫГРУЗИТЬиЗАГРУЗИТЬ). - Если ничего не помогает, перепишите запрос на прямой SQL (но учитывайте ограничения 1С).
Можно ли в 1С использовать транзакции в SQL-запросах?
Технически да, но с оговорками:
- Встроенные транзакции 1С (
НачатьТранзакцию) не распространяются на прямые SQL-запросы. - Для SQL-транзакций нужно использовать
BEGIN TRANSACTIONиCOMMITпрямо в тексте запроса, но 1С может прервать выполнение, если запрос займёт слишком много времени. - Лучший вариант — вынести сложную логику в хранимые процедуры на стороне СУБД.