Creatio development guide
PDF
Описание платформы
Это документация Creatio версии 7.15.0. Мы рекомендуем использовать новую версию документации.

Функциональность многострочного добавления данных. Класс Insert

Glossary Item Box

Общие сведения

Начиная с версии 7.12.4 в приложении появилась функциональность многострочной вставки. Она доступна на уровне класса Insert и ее работа определяется методом Values().

При вызове метода Values() все последующие вызовы Set() попадают в новый экземпляр ColumnsValues. При построении запроса, если в коллекции ColumnsValuesCollection встречается более одного набора данных, то будет построен запрос с несколькими блоками Values().

Например:

new Insert(UserConnection)
.Into("Table")
.Values()
    .Set("Column1", Column.Const(1))
    .Set("Column2", Column.Const(1))
    .Set("Column3", Column.Const(1))
.Values()
    .Set("Column1", Column.Const(2))
    .Set("Column2", Column.Const(2))
    .Set("Column3", Column.Const(2))
.Values()
    .Set("Column1", Column.Const(3))
    .Set("Column2", Column.Const(3))
    .Set("Column3", Column.Const(3))
.Execute();

В результате будет сформирован следующий SQL-запрос:

--Для MSSQL или PostgreSQL
INSERT INTO [dbo].[Table] (Column1, Column2, Column3)
VALUES (1, 1, 1),
    (2, 2, 2),
    (3, 3, 3)
    
-- Для Oracle
INSERT ALL
    into Table (column1, column2, column3) values (1, 1, 1)
    into Table (column1, column2, column3) values (2, 2, 2)
    into Table (column1, column2, column3) values (3, 3, 3)
SELECT * FROM dual

ВАЖНО

Код в примерах показывает различные способы передачи параметров в запрос. При разработке проекта учитывайте, что в метод Column.Const не следует передавать параметры, контролируемые пользователем, так как это может привести к потенциальным sql-инъекциям.

Особенности использования

1. При использовании Column.Parameter в выражении Set() необходимо помнить про ограничение 2100 параметров в MS SQL.

2. Класс Insert не может самостоятельно разбивать запрос на несколько, если в нем находится больше параметров, чем нужно. Разбиение на несколько запросов должно быть реализовано разработчиком. Например:

IEnumerable<IEnumerable<ImportEntity>> GetImportEntitiesChunks(IEnumerable<ImportEntity> entities,
                IEnumerable<ImportColumn> keyColumns) {
    var entitiesList = entities.ToList();
    var columnsList = keyColumns.ToList();
    var maxParamsPerChunk = Math.Abs(MaxParametersCountPerQueryChunk / columnsList.Count + 1);
    var chunksCount = (int)Math.Ceiling(entitiesList.Count / (double)maxParamsPerChunk);
    return entitiesList.SplitOnParts(chunksCount);
}

var entitiesList = GetImportEntitiesChunks(entities, importColumns);
entitiesList.AsParallel().AsOrdered()
    .ForAll(entitiesBatch => {
        try {
            var insertQuery = GetBufferedImportEntityInsertQuery();
            foreach (var importEntity in entitiesBatch) {
                insertQuery.Values();
                SetBufferedImportEntityInsertColumnValues(importEntity, insertQuery,
                        importColumns);
                insertQuery.Set("ImportSessionId", Column.Const(importSessionId));
            }
            insertQuery.Execute();
        } catch (Exception e) {
            //...
        }
});

3. Класс Insert() не проводит валидацию на соответствие количества колонок и количества условий Set(). Например, есть результирующий SQL-запрос:

INSERT INTO [dbo].[Table] (Column1, Column2, Column3)
Values (1, 2), (1, 2, 3)

В таком случае возникнет исключение на уровне работы СУБД. Подобная валидация не лежит в зоне ответственности класса Insert и зависит только от разработчика.

© Terrasoft 2002-2020.

Был ли данный материал полезен?

Как можно улучшить эту статью?