Документация

Документация по разработке bpm’online
PDF
Документация по разработке
Описание платформы
Функциональность многострочного добавления данных

Glossary Item Box

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

Начиная с версии 7.12.4 вbpm'online появилась функциональность многострочной вставки. Она доступна на уровне класса 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

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

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-2018.

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

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