хранение "древовидной" информации
Релиб
Форумы       Участники    Календарь    Кто он-лайн?
Добро пожаловать, гость ( Вход | Регистрация )
        



хранение "древовидной" информации Expand / Collapse
Автор
Сообщение
08.12.2000 10:13
новичок

новичокновичокновичокновичокновичокновичокновичокновичок

участник
Last Login: 08.12.2000 10:10
Сообщ.: 3, Visits: 34
Как организовать хранение "древовидной" информации (структура
предприятия,структура документации и т.д.),с неограниченным уровнем
вложенности?Не хотелось бы создавать для каждой ветки таблицу,может
быть есть другое решение?
Сообщ. #702276
08.12.2000 11:19
новичок

новичокновичокновичокновичокновичокновичокновичокновичок

участник
Last Login: 08.12.2000 11:18
Сообщ.: 1, Visits: 12
"Registry" в базе данных
--------------------------------------------------------------------------------

Автор: Владимир Переплетчик, КИТ, Белгород.
Вашему вниманию предлагается пример организации данных типа Registry в БД. В таблице хранятся разнородные данные, процедуры обеспечивают выбору всей иерархии в нужном порядке и поиск по ключу. Хотя это и не самый быстрый способ (безусловно, обращение к базе данных медленнее чем к Registry Windows 95 или Windows NT), зато есть возможность настойки системы .
Такую структуру можно использовать для хранения настроек пользовател независимо от клиентского компьютера, с которого пользователь работает с базой данных (естественно на каждого - свои настройки) и т.п.

Примечание: При вставке строк в качестве имени ключа (key_name) не допускаются символы ''\''. Для процедуры Find_Regitry_Entry строку FULLKEY нужно задавать как ''rootkey1\secondkey\''.

Если вы поместите этот текст в скрипт, то не забудьте добавить в конец файла пару пустых переводов строки.



--------------------------------------------------------------------------------

CONNECT "C:\MYDATABASE.GDB" USER "SYSDBA" PASSWORD "masterkey";

/* Таблица для хранения данных "Regitry" */
CREATE TABLE REGISTRY (
Key_code integer not null,
Key_parent integer ,
Key_name char(64) not null,
Key_type smallint not null,
Key_string char(255) ,
Key_integer integer,
Key_date date ,
Key_float double precision,
Key_blob blob,
constraint pk_registry primary key(Key_code));

ALTER TABLE REGISTRY ADD CONSTRAINT FK_REGISTRY
FOREIGN KEY (key_parent) references REGISTRY;

CREATE EXCEPTION NOT_UNIQUE_NAME ''Not unique name in group'';
CREATE EXCEPTION INTEGRITY_ERROR ''Error in hierarchy'';

SET TERM !! ;

CREATE PROCEDURE GET_REGISTRY_SUBKEYS(parent_code integer, lev smallint)
RETURNS( Key_code integer,
Key_name varchar(64),
Key_type smallint,
level_num smallint)
AS
BEGIN
FOR SELECT Key_code, Key_name, Key_type
FROM REGISTRY
WHERE Key_parent = :parent_code
INTO :Key_code, :Key_name, :Key_type
DO
BEGIN
level_num = lev;
SUSPEND;
FOR SELECT Key_code, Key_name, level_num, Key_type
FROM GET_REGISTRY_SUBKEYS(:Key_code, :lev+1)
INTO :Key_code, :Key_name, :level_num, :Key_type
DO SUSPEND;
END
EXIT;
END!!

CREATE PROCEDURE GET_REGISTRY
RETURNS( Key_code integer,
Key_name varchar(64),
Key_type smallint,
level_num smallint)
AS
BEGIN
FOR SELECT Key_code, Key_name, Key_type
FROM REGISTRY
WHERE Key_parent is null
INTO :Key_code, :Key_name, :Key_type
DO
BEGIN
level_num = 0;
SUSPEND;
FOR SELECT Key_code, Key_name, level_num, key_type
FROM GET_REGISTRY_SUBKEYS(:Key_code, 1)
INTO :Key_code, :Key_name, :level_num, :key_type
DO SUSPEND;
END
EXIT;
END!!

CREATE PROCEDURE FIND_REGISTRY_SUBKEY( FullKey VarChar(1000),
PartialKey VarChar(1000),
Parent Integer)
RETURNS( Key_code integer,
Key_name varchar(64),
Key_type smallint )
AS
BEGIN
SELECT Key_code, Key_name, key_type
FROM REGISTRY
WHERE Key_parent = :parent AND
:FullKey LIKE :PartialKey||key_name||''\%''
INTO :Key_code, :Key_name, :key_type;

IF (Key_code is null) THEN EXIT;

IF (PartialKey||Key_name||''\'' <> FullKey) THEN
BEGIN
key_type = NULL;
SELECT Key_code, Key_name, key_type
FROM FIND_REGISTRY_SUBKEY( :FullKey, :PartialKey||:key_name||''\'', :Key_code)
INTO :Key_code, :Key_name, :key_type;
END

IF (Key_type is not null) THEN SUSPEND;
END!!

CREATE PROCEDURE FIND_REGISTRY_ENTRY( FullKey VarChar(1000))
RETURNS( Key_code integer,
Key_name varchar(64),
Key_type smallint)
AS
BEGIN
SELECT Key_code, Key_name, key_type
FROM REGISTRY
WHERE Key_parent is null AND
:FullKey LIKE key_name||''\%''
INTO :Key_code, :Key_name, :key_type;

IF (Key_code is null) THEN EXIT;

IF (Key_name||''\'' <> FullKey) THEN
BEGIN
key_type = NULL;
SELECT Key_code, Key_name, key_type
FROM FIND_REGISTRY_SUBKEY( :FullKey, :key_name||''\'', :Key_code)
INTO :Key_code, :Key_name, :key_type;
END

IF (Key_type is not null) THEN SUSPEND;
END!!

CREATE TRIGGER REGISTRY_INSERT FOR REGISTRY
BEFORE INSERT AS
BEGIN
IF (new.key_parent is null) THEN

IF (EXISTS(SELECT key_name FROM REGISTRY
WHERE key_parent is null AND
key_name = new.key_name)) THEN
EXCEPTION NOT_UNIQUE_NAME;

IF (new.key_parent is not null) THEN
IF (EXISTS(SELECT key_name FROM REGISTRY
WHERE key_parent=new.key_parent AND key_name = new.key_name)) THEN
EXCEPTION NOT_UNIQUE_NAME;

SELECT MAX(key_code) FROM REGISTRY
INTO new.key_code;

IF (new.key_code is null) then new.key_code = 1;
ELSE new.key_code = new.key_code + 1;
END!!

CREATE TRIGGER REGISTRY_UPDATE FOR REGISTRY
BEFORE UPDATE
AS
BEGIN
IF (new.key_name <> old.key_name) THEN
BEGIN
IF (new.key_parent is null) THEN
IF (EXISTS(SELECT key_name FROM REGISTRY
WHERE key_parent is null AND key_name = new.key_name)) THEN
EXCEPTION NOT_UNIQUE_NAME;

IF (new.key_parent is not null) THEN
IF (EXISTS(SELECT key_name FROM REGISTRY
WHERE key_parent=new.key_parent AND key_name = new.key_name)) THEN
EXCEPTION NOT_UNIQUE_NAME;
END

IF ((EXISTS(SELECT key_code
FROM GET_REGISTRY_SUBKEYS(new.key_code,0)
WHERE key_code = new.key_parent)) OR
(new.key_parent = new.key_code)) THEN
EXCEPTION INTEGRITY_ERROR;
END!!

SET TERM ; !!
COMMIT;




--------------------------------------------------------------------------------

Сообщ. #702277
08.12.2000 12:39
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

администратор
Last Login: 13.11.2007 13:41
Сообщ.: 4 421, Visits: 49 251
2aydarsky

Хотелось бы знать где (СУБД) и чем (среда разработки)? А то так я могу сказать, что используйте для этого СУБД MDBS IV или Titanium (http://www.mdbs.com), которые как раз для этого и предназначены, но, думаю, что вы не используете эти СУБД, т.к. на весь х-СССР она есть только в одном месте :-)
Сообщ. #702280
08.12.2000 21:05
новичок

новичокновичокновичокновичокновичокновичокновичокновичок

участник
Last Login: 08.12.2000 10:10
Сообщ.: 3, Visits: 34
Спасибо за ответы,идея понятна.Задача состоит в написании чего-то типа эл.каталога для разносортной документации предприятия.Средства- VB6 и Access97.Файлы документов лежат на диске,в базе каталогизированы ссылки на эти файлы и прочая инфа
Сообщ. #702299
« пред. тема | след. тема »


Эту тему читают Expand / Collapse
Посетители: 0 (0 гостей, 0 участников, 0 скрыт.участников)
Сейчас нет участников, просматривающих тему.
Модераторы: Alexey, boombastik, bazile, pl

Время GMT +3:00, Сейчас 5:29