DML: язык управления данными

Язык запросов DaJet реализует DML подмножество своего языка исключительно для достижения вспомогательных целей. В частности для реализации команды CONSUME.

Любая интеграция с платформой 1С:Предприятие 8 путём прямой записи каких-либо данных непосредственно в таблицы базы данных 1С является потенциально ошибочной.

Причиной этому служит то, что платформа 1С:Предприятие 8 выполняет запись в базу данных при помощи встроенных в неё объектов типа "СправочникОбъект", "ДокументОбъект", "РегистрСведенийНаборЗаписей" и так далее. Все эти объекты являются частью подсистемы ORM (object-relational mapping) платформы.

Подсистема ORM 1С, в свою очередь, имеет ряд программных обработчиков событий записи объектов в базу данных. Например, подписки на события и обработчики модулей объектов, которые выполняются в транзакции записи объекта в базу данных и часто (почти всегда) содержат бизнес-логику прикладного решения на языке 1С.

Таким образом, непосредственная запись данных напрямую в таблицы базы данных прикладных объектов платформы 1С:Предприятие 8 игнорирует существование обработчиков этих событий, то есть они не выполняются!

Команда INSERT

Особенностью команды INSERT в реализации языка запросов DaJet является сопоставление значений полей источника данных (выборка записей) с полями приёмника (таблицы) по их именам.

Это принципиально отличается от классического синтаксиса SQL, который выполняет сопоставление данных источника и приёмника согласно указанной пользователем последовательности, то есть по их позиции в этой последовательности.

Ещё одной особенностью команды INSERT в реализации DaJet является то, что все, не указанные источником данные, но имеющиеся в приёмнике, будут автоматически установлены в значения по умолчанию.

Например, источником данных ниже является общее табличное выражение source, которое предоставляет для вставки в таблицу "Справочник.Номенклатура" следующие данные: Ссылка, Код и Наименование. Все остальные реквизиты справочника будут заполнены значениями по умолчанию!

DECLARE @new_code string = 'ТЦ-000001';
DECLARE @new_name string = 'Новая номенклатура';
DECLARE @new_uuid Справочник.Номенклатура = '0C9150E8-6B51-4DAB-9B14-0F857013EA8B';

CREATE COMPUTED TABLE source AS
(
  SELECT @new_uuid AS Ссылка,
         @new_code AS Код,
         @new_name AS Наименование
)
INSERT Справочник.Номенклатура FROM source

-- Проверка результата выполнения команды INSERT
SELECT Ссылка, Код, Наименование
  FROM Справочник.Номенклатура
 WHERE Ссылка = @new_uuid

Команда UPDATE

Команда UPDATE работает аналогично команде INSERT, получая данные из выборки.

DECLARE @code string = '222';
DECLARE @name string = 'Валюта ∫';

CREATE COMPUTED TABLE source AS
(
  SELECT @code AS Код,
         @name AS Значение
)
UPDATE Справочник.Валюты FROM source
 WHERE Код = source.Код
   SET Наименование = source.Значение

-- Проверка результата выполнения команды UPDATE
SELECT Ссылка, Код, Наименование
  FROM Справочник.Валюты
 WHERE Код = @code

Команда UPSERT

Команда UPSERT является комбинацией последовательного выполнения команд UPDATE и INSERT. Правила сопоставления свойств объектов источника и приёмника здесь действуют в той же мере, в которой они были описаны для команды INSERT.

Предложение WHERE используется в качестве синхронизации данных между источником и приёмником. Если условие выполняется, то будет выполняться UPDATE по данным, предоставленным в предложении SET. В противном случае будет выполнена команда INSERT по данным, предоставленным источником source.

Команда UPSERT может выполняться с необязательной опцией IGNORE UPDATE. В таком случае, если условие WHERE выполняется, то команда INSERT не выполняется. Команада UPDATE не выполняется в любом случае. Другими словами данный вариант синтаксиса UPSERT выполняет только команду INSERT и только если предложение WHERE вернёт отрицательный (ложный) результат.

DECLARE @code string = '333';
DECLARE @name string = 'Рубль 333';
DECLARE @entity Справочник.Валюты = 'CC70FDD5-14CD-494E-AA29-45B106544B34';

CREATE COMPUTED TABLE source AS
(
  SELECT @entity AS Ссылка,
         @code   AS Код,
         @name   AS Наименование
)
UPSERT Справочник.Валюты [IGNORE UPDATE] FROM source
 WHERE Код = source.Код
   SET Наименование = source.Наименование

-- Проверка результата выполнения команды UPSERT
SELECT Ссылка, Код, Наименование
  FROM Справочник.Валюты
 WHERE Код = @code

Команда DELETE

Команда DELETE реализована максимально просто.

-- Полная очистка таблицы
DELETE Справочник.Валюты

-- Частичная очистка по условию
DELETE Справочник.Валюты WHERE Код = '840'