Обработка изменений хранимыми процедурами
Разработчики могут использовать хранимые процедуры для проверки вводимых данных или для сохранения изменений в базу данных сразу после изменения ячеек.
Эти обработчики можно настроить в таблице xls.handlers для всех колонок или только для некоторых.
Ниже приведен пример настройки для всех колонок:
| ID | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | EVENT_NAME | HANDLER_SCHEMA | HANDLER_NAME | HANDLER_TYPE | HANDLER_CODE |
|---|---|---|---|---|---|---|---|---|
| s02 | usp_cashbook3 | Change | s02 | usp_cashbook3_change | PROCEDURE |
Эту настройку можно не создавать, если имя процедуры обработчика заканчивается на _change, как в приведенном примере.
Ниже приведен пример настройки для обработки только двух заданных колонок:
| ID | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | EVENT_NAME | HANDLER_SCHEMA | HANDLER_NAME | HANDLER_TYPE | HANDLER_CODE |
|---|---|---|---|---|---|---|---|---|
| s02 | usp_cashbook3 | item_id | Change | s02 | usp_cashbook3_change | PROCEDURE | ||
| s02 | usp_cashbook3 | company_id | Change | s02 | usp_cashbook3_change | PROCEDURE |
Детали реализации
SaveToDB и DBEdit вызывают указанные процедуры на стороне клиента.
DBGate предоставляет доступ к процедурам через метод POST и добавляет обработчики в метаданные объектов или колонок.
ODataDB создает операции ActionImport для каждой процедуры и добавляет аннотации в EntityType или его поля.
Надстройка SaveToDB поддерживает метаданные DBGate и ODataDB для настройки таких обработчиков.
Параметры хранимых процедур
Хранимые процедуры могут принимать параметры, которые получают значения по следующим правилам:
- Значения из колонок данных с тем же именем. Например, параметры @id и @name получают значения из колонок id и name.
- Значения параметров запроса с тем же именем. Например, параметр @account_id может использовать значение параметра @account_id из запроса данных.
- Значения именованных ячеек Excel. Например, параметр @customer_id может получать значение из именованной ячейки customer_id (только в надстройке SaveToDB).
- Специальные контекстные значения, такие как @rownum или @transaction_id.
Наиболее полезные контекстные параметры:
- @column_name — имя колонки ячейки.
- @cell_value — строковое значение ячейки.
- @cell_number_value — числовое значение ячейки.
- @cell_datetime_value — значение ячейки типа datetime.
См. полный список контекстных параметров в статье Контекстные параметры.
Параметры @cell_number_value и @cell_datetime_value можно использовать для получения типизированных значений, что полезно для проверки корректности вводимых данных. Например, если типизированное значение равно NULL, а строковое — нет.
В некоторых случаях имена колонок таблицы данных могут содержать символы, которые нельзя использовать в именах параметров. Например, "customer name".
В таких случаях можно заменить запрещенные символы в именах параметров на их XML-кодировку. Например, "customer_x0020_name".
См. Соглашение по именам параметров.
Примеры хранимых процедур для обработки изменения ячеек
Ниже приведены примеры хранимых процедур для всех поддерживаемых платформ баз данных.
Используйте эти примеры для разрешения конфликтов имен параметров и полей обновляемых таблиц.
SQL Server | MySQL | PostgreSQL | Oracle | Snowflake
Пример хранимой процедуры обработки изменения ячеек для Microsoft SQL Server
CREATE PROCEDURE [s02].[usp_cashbook3_change]
@column_name nvarchar(255),
@cell_value nvarchar(255) = NULL,
@cell_number_value money = NULL,
@cell_datetime_value date = NULL,
@id int = NULL
AS
BEGIN
SET NOCOUNT ON;
IF @column_name = 'debit'
UPDATE s02.cashbook SET debit = @cell_number_value WHERE id = @id;
ELSE IF @column_name = 'credit'
UPDATE s02.cashbook SET credit = @cell_number_value WHERE id = @id;
ELSE IF @column_name = 'item_id'
UPDATE s02.cashbook SET item_id = @cell_number_value WHERE id = @id;
ELSE IF @column_name = 'company_id'
UPDATE s02.cashbook SET company_id = @cell_number_value WHERE id = @id;
ELSE IF @column_name = 'account_id'
UPDATE s02.cashbook SET account_id = @cell_number_value WHERE id = @id;
ELSE IF @column_name = 'date'
UPDATE s02.cashbook SET [date] = @cell_datetime_value WHERE id = @id;
END
Пример хранимой процедуры обработки изменения ячеек для MySQL
CREATE PROCEDURE s02.usp_cashbook3_change (
column_name varchar(128),
cell_value varchar(255),
cell_number_value varchar(255),
cell_datetime_value varchar(255),
id int
)
BEGIN
IF column_name = 'date' THEN
UPDATE s02.cashbook t SET date = cell_datetime_value WHERE t.id = id;
ELSEIF column_name = 'account_id' THEN
UPDATE s02.cashbook t SET account_id = CAST(cell_number_value AS unsigned) WHERE t.id = id;
ELSEIF column_name = 'item_id' THEN
UPDATE s02.cashbook t SET item_id = CAST(cell_number_value AS unsigned) WHERE t.id = id;
ELSEIF column_name = 'company_id' THEN
UPDATE s02.cashbook t SET company_id = CAST(cell_number_value AS unsigned) WHERE t.id = id;
ELSEIF column_name = 'debit' THEN
UPDATE s02.cashbook t SET debit = cell_number_value WHERE t.id = id;
ELSEIF column_name = 'credit' THEN
UPDATE s02.cashbook t SET credit = cell_number_value WHERE t.id = id;
END IF;
END
//
Пример хранимой процедуры обработки изменения ячеек для PostgreSQL
CREATE OR REPLACE FUNCTION s02.usp_cashbook3_change (
column_name varchar,
cell_value varchar,
cell_number_value double precision,
cell_datetime_value date,
id integer
)
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
IF column_name = 'id' THEN
RAISE EXCEPTION 'Do not change the id column';
RETURN;
ELSIF column_name = 'date' THEN
IF cell_datetime_value IS NULL AND cell_value IS NOT NULL THEN
RAISE EXCEPTION 'Date requires a date value';
RETURN;
END IF;
UPDATE s02.cashbook p SET date = cell_datetime_value WHERE p.id = usp_cashbook3_change.id;
ELSIF column_name = 'debit' THEN
IF cell_number_value IS NULL AND cell_value IS NOT NULL THEN
RAISE EXCEPTION 'Debit requires a number value';
RETURN;
END IF;
UPDATE s02.cashbook p SET debit = cell_number_value WHERE p.id = usp_cashbook3_change.id;
ELSIF column_name = 'credit_id' THEN
IF cell_number_value IS NULL AND cell_value IS NOT NULL THEN
RAISE EXCEPTION 'Credit requires a number value';
RETURN;
END IF;
UPDATE s02.cashbook p SET credit_id = cell_number_value WHERE p.id = usp_cashbook3_change.id;
ELSIF column_name = 'account_id' THEN
UPDATE s02.cashbook p SET account_id = CAST(cell_number_value AS integer) WHERE p.id = usp_cashbook3_change.id;
ELSIF column_name = 'company_id' THEN
UPDATE s02.cashbook p SET company_id = CAST(cell_number_value AS integer) WHERE p.id = usp_cashbook3_change.id;
ELSIF column_name = 'item_id' THEN
UPDATE s02.cashbook p SET item_id = CAST(cell_number_value AS integer) WHERE p.id = usp_cashbook3_change.id;
ELSE
RAISE NOTICE 'The cashbook table does not contain the % column', column_name;
RETURN;
END IF;
IF NOT FOUND THEN
RAISE NOTICE 'The record with the id % not found', id;
RETURN;
END IF;
END
$$;
Пример хранимой процедуры обработки изменения ячеек для Oracle Database
CREATE OR REPLACE PROCEDURE S02.USP_CASHBOOK3_CHANGE (
COLUMN_NAME VARCHAR2,
CELL_VALUE VARCHAR2,
CELL_NUMBER_VALUE DOUBLE PRECISION,
CELL_DATETIME_VALUE DATE,
ID NUMBER
)
AS
BEGIN
IF COLUMN_NAME = 'DATE' THEN
UPDATE S02.CASHBOOK P SET "DATE" = CELL_DATETIME_VALUE WHERE P.ID = USP_CASHBOOK3_CHANGE.ID;
ELSIF COLUMN_NAME = 'DEBIT' THEN
UPDATE S02.CASHBOOK P SET DEBIT = CELL_NUMBER_VALUE WHERE P.ID = USP_CASHBOOK3_CHANGE.ID;
ELSIF COLUMN_NAME = 'CREDIT' THEN
UPDATE S02.CASHBOOK P SET CREDIT = CELL_NUMBER_VALUE WHERE P.ID = USP_CASHBOOK3_CHANGE.ID;
ELSIF COLUMN_NAME = 'ACCOUNT_ID' THEN
UPDATE S02.CASHBOOK P SET ACCOUNT_ID = CAST(CELL_NUMBER_VALUE AS NUMBER) WHERE P.ID = USP_CASHBOOK3_CHANGE.ID;
ELSIF COLUMN_NAME = 'COMPANY_ID' THEN
UPDATE S02.CASHBOOK P SET COMPANY_ID = CAST(CELL_NUMBER_VALUE AS NUMBER) WHERE P.ID = USP_CASHBOOK3_CHANGE.ID;
ELSIF COLUMN_NAME = 'ITEM_ID' THEN
UPDATE S02.CASHBOOK P SET ITEM_ID = CAST(CELL_NUMBER_VALUE AS NUMBER) WHERE P.ID = USP_CASHBOOK3_CHANGE.ID;
END IF;
END;
/
Пример хранимой процедуры обработки изменения ячеек для Snowflake
Snowflake поддерживает хранимые процедуры на языке JavaScript, которые используются аналогично.