Andrei K. <
gs1...@gmail.com> писал(а) в
своём письме Thu, 10 Apr 2014 12:32:31 +0400:
>
> Для сложных обработок будет крайне нехватать объектов
> типа Dictionary (его же можно использовать как массив). Конечно,
> можно обойтись временными таблицами, но работа с ними
> будет гораздо более громоздкой и их надо создавать заранее.
>
> Функции, которые можно было бы добавить:
>
> // добавляет или присваивает значение по ключу
> RDB$DICTIONARY_ADD(context, dictionary_name, key, value)
>
> // проверяет наличие ключа
> RDB$DICTIONARY_HAS(context, dictionary_name, key)
>
> // возвращает количество элементов
> RDB$DICTIONARY_COUNT(context, dictionary_name)
>
> // удаляет элемент
> RDB$DICTIONARY_REMOVE(context, dictionary_name, key)
>
> //очищает словарь
> RDB$DICTIONARY_CLEAR(context, dictionary_name)
>
> context здесь это 'USER_SESSION' или 'USER_TRANSACTION'
>
написал модуль реализующий это. Я думаю при желании его можно заточить под
твои нужды
CREATE GLOBAL TEMPORARY TABLE SESSION_DICTIONARY (
NAME VARCHAR(31) NOT NULL,
KEY_NAME VARCHAR(31) NOT NULL,
DIC_VALUE VARCHAR(255)
) ON COMMIT PRESERVE ROWS;
ALTER TABLE SESSION_DICTIONARY ADD CONSTRAINT PK_SESSION_DICTIONARY
PRIMARY KEY (NAME, KEY_NAME);
CREATE GLOBAL TEMPORARY TABLE TRANSACTION_DICTIONARY (
NAME VARCHAR(31) NOT NULL,
KEY_NAME VARCHAR(31) NOT NULL,
DIC_VALUE VARCHAR(255)
) ON COMMIT DELETE ROWS;
ALTER TABLE TRANSACTION_DICTIONARY ADD CONSTRAINT
PK_TRANSACTION_DICTIONARY PRIMARY KEY (NAME, KEY_NAME);
CREATE EXCEPTION E_INCORRECT_DICTIONARY_CONTEXT 'Не корректный контекст
для словаря';
SET TERM ^;
CREATE OR ALTER PACKAGE DICTIONARY
AS
begin
-- добавляет или присваивает значение по ключу
function ADD_ITEM(context varchar(31),
dictionary_name varchar(31),
key_name varchar(31),
dic_value varchar(255)) returns varchar(255);
-- проверяет наличие ключа
function HAS_ITEM(context varchar(31),
dictionary_name varchar(31),
key_name varchar(31)) returns boolean;
-- возвращает количество элементов
function COUNT_ITEM(context varchar(31),
dictionary_name varchar(31)) returns int;
-- удаляет элемент
function REMOVE_ITEM(context varchar(31),
dictionary_name varchar(31),
key_name varchar(31)) returns varchar(255);
--очищает словарь
function CLEAR(context varchar(31),
dictionary_name varchar(31)) returns int;
-- возвращает элемент
function GET_ITEM(context varchar(31),
dictionary_name varchar(31),
key_name varchar(31)) returns varchar(255);
end^
RECREATE PACKAGE BODY DICTIONARY
AS
begin
/*************************************/
-- Реализация приватных функций
/*************************************/
-- проверяет правильность контекста
procedure CHECK_CONTEXT(context varchar(31))
as
begin
if (UPPER(context) not in ('USER_SESSION', 'USER_TRANSACTION')) then
exception E_INCORRECT_DICTIONARY_CONTEXT;
end
/*************************************/
-- Реализация публичных функций
/*************************************/
-- добавляет или присваивает значение по ключу
function ADD_ITEM(context varchar(31),
dictionary_name varchar(31),
key_name varchar(31),
dic_value varchar(255)) returns varchar(255)
as
begin
execute procedure CHECK_CONTEXT(:context);
if (UPPER(context) = 'USER_SESSION') then
begin
insert into SESSION_DICTIONARY(name, key_name, dic_value)
values (:dictionary_name, :key_name, :dic_value);
return dic_value;
end
if (UPPER(context) = 'USER_TRANSACTION') then
begin
insert into TRANSACTION_DICTIONARY(name, key_name, dic_value)
values (:dictionary_name, :key_name, :dic_value);
return dic_value;
end
end
-- проверяет наличие ключа
function HAS_ITEM(context varchar(31),
dictionary_name varchar(31),
key_name varchar(31)) returns boolean
as
begin
execute procedure CHECK_CONTEXT(:context);
if (UPPER(context) = 'USER_SESSION') then
begin
return EXISTS(select *
from SESSION_DICTIONARY
where name = :dictionary_name and
key_name = :key_name);
end
if (UPPER(context) = 'USER_TRANSACTION') then
begin
return EXISTS(select *
from TRANSACTION_DICTIONARY
where name = :dictionary_name and
key_name = :key_name);
end
end
-- возвращает количество элементов
function COUNT_ITEM(context varchar(31),
dictionary_name varchar(31)) returns int
as
begin
execute procedure CHECK_CONTEXT(:context);
if (UPPER(context) = 'USER_SESSION') then
begin
return (select count(*)
from SESSION_DICTIONARY
where name = :dictionary_name);
end
if (UPPER(context) = 'USER_TRANSACTION') then
begin
return (select count(*)
from TRANSACTION_DICTIONARY
where name = :dictionary_name);
end
end
-- удаляет элемент
function REMOVE_ITEM(context varchar(31),
dictionary_name varchar(31),
key_name varchar(31)) returns varchar(255)
as
declare variable xValue varchar(255);
begin
execute procedure CHECK_CONTEXT(:context);
if (UPPER(context) = 'USER_SESSION') then
begin
delete from SESSION_DICTIONARY
where name = :dictionary_name and
key_name = :key_name
returning dic_value
into xValue;
end
if (UPPER(context) = 'USER_TRANSACTION') then
begin
delete from TRANSACTION_DICTIONARY
where name = :dictionary_name and
key_name = :key_name
returning dic_value
into xValue;
end
return xValue;
end
--очищает словарь
function CLEAR(context varchar(31),
dictionary_name varchar(31)) returns int
as
begin
execute procedure CHECK_CONTEXT(:context);
if (UPPER(context) = 'USER_SESSION') then
begin
delete from SESSION_DICTIONARY
where name = :dictionary_name;
return ROW_COUNT;
end
if (UPPER(context) = 'USER_TRANSACTION') then
begin
delete from TRANSACTION_DICTIONARY
where name = :dictionary_name;
return ROW_COUNT;
end
end
-- возвращает элемент
function GET_ITEM(context varchar(31),
dictionary_name varchar(31),
key_name varchar(31)) returns varchar(255)
as
declare variable xValue varchar(255);
begin
execute procedure CHECK_CONTEXT(:context);
if (UPPER(context) = 'USER_SESSION') then
begin
select dic_value
from SESSION_DICTIONARY
where name = :dictionary_name and
key_name = :key_name
into xValue;
end
if (UPPER(context) = 'USER_TRANSACTION') then
begin
select dic_value
from TRANSACTION_DICTIONARY
where name = :dictionary_name and
key_name = :key_name
into xValue;
end
return xValue;
end
end^
SET TERM ;^