Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Firebird, Interbase > копирование структуры с id, parent_id, text


Автор: Sed0Y 16.4.2010, 14:43
есть у меня таблица (в firebird), с полями FID, FPARENT_ID, FTEXT

есть некие данные типа:

Код


id   parent_id         text
1    -1              aaa
2    1              bbb
3    1              ccc
4    3              ddd
5    4              ooo
6    1              yyy
7    6              kkk



нужно скопировать в ту же таблицу что бы бала та же структура только новые ИД и парентИД


Код

id   parent_id        text
10    -1             aaa
11    10             bbb
12    10             ccc
13    12             ddd
14    13             ooo
15    10             yyy
16    15             kkk



как это реализовать - Можно программно, можно ХПками?

Автор: Gluttton 16.4.2010, 18:33
Т.е. не меняя "вхождения" одних элементов в другие нужно все значения первичных и внешних ключей увеличить на 9?

Автор: Sed0Y 17.4.2010, 01:30
Цитата(Gluttton @ 16.4.2010,  18:33)
Т.е. не меняя "вхождения" одних элементов в другие нужно все значения первичных и внешних ключей увеличить на 9?

нет, увеличивать их не нужно
нужно создать такую же структуру, только что бы ли другие ИД (gen_id())

Автор: Gluttton 17.4.2010, 01:38
Что понимается под структурой?
Структура таблицы в БД? Или же структура дерева хранимых в БД элементов?


Автор: Sed0Y 17.4.2010, 02:36
Цитата(Gluttton @ 17.4.2010,  01:38)
Что понимается под структурой?
Структура таблицы в БД? Или же структура дерева хранимых в БД элементов?

структура дерева хранимых в БД элементов

Автор: Gluttton 17.4.2010, 02:40
Цитата(Sed0Y @  17.4.2010,  02:36 Найти цитируемый пост)
структура дерева

Рекурсивно обходишь дерево и обновляешь элементы...
http://forum.vingrad.ru/index.php?showtopic=276790&view=findpost&p=1998789

Автор: Sed0Y 17.4.2010, 03:03
Цитата(Gluttton @ 17.4.2010,  02:40)
Цитата(Sed0Y @  17.4.2010,  02:36 Найти цитируемый пост)
структура дерева

Рекурсивно обходишь дерево и обновляешь элементы...
http://forum.vingrad.ru/index.php?showtopic=276790&view=findpost&p=1998789

Gluttton, вы меня конечно простите, но я не на столько сильно владею СКЛ - я не понимаю :( особенно как рекурсивно обойти и обновить элементы...   smile 
если Вас не затруднит, не могли бы пример для меня сделать?
а то это все дело мне нужно на завтра до вечера доделать....

Автор: Gluttton 17.4.2010, 03:42
Цитата(Sed0Y @  17.4.2010,  03:03 Найти цитируемый пост)
если Вас не затруднит

Я задачу так и не понял!
Что дано - ясно (таблица, ключи, тестовые данные), а вот, что нужно сделать я так и не могу понять?


Цитата(Sed0Y @  17.4.2010,  01:30 Найти цитируемый пост)
нужно создать такую же структуру, только что бы ли другие ИД (gen_id()) 

Что значит другие? Откуда они беруться? Расчитываются?
Изменить нужно все записи или только определенные?

Автор: Sed0Y 17.4.2010, 04:13
Цитата(Gluttton @ 17.4.2010,  03:42)
Цитата(Sed0Y @  17.4.2010,  03:03 Найти цитируемый пост)
если Вас не затруднит

Я задачу так и не понял!
Что дано - ясно (таблица, ключи, тестовые данные), а вот, что нужно сделать я так и не могу понять?


Цитата(Sed0Y @  17.4.2010,  01:30 Найти цитируемый пост)
нужно создать такую же структуру, только что бы ли другие ИД (gen_id()) 

Что значит другие? Откуда они беруться? Расчитываются?
Изменить нужно все записи или только определенные?

Вот картинка, может так будет понятно:

1- картинка, это у наст есть уже что-то
2 - мы ее хотим сохранить как отдельную
3 - мы имеем 2-к орг структуры с одинаковой структурой (дерево)
http://www.radikal.ru

Автор: Gluttton 17.4.2010, 11:25
Я так понимаю, что есть некоторая БД, а в ней таблица с древовидной структурой.
Некое клиентское приложение обеспечивает доступ к данным этой таблицы (судя по всему с возможностью модификации данных)...
Задача сохринить в БД внесенные на стороне клиентского приложения изменения...

Это то, что я понял из картинки smile , но вот зачем "перезаписывать" ключевые поля я так и не понял... Что мешает копировать данные один-в-один?

Автор: Gluttton 17.4.2010, 11:50
Если FPARENT_ID является внешним ключем и на него наложено ограничение каскадного обновления, то вопрос обновления ключевых полей решается автомитически на уровне СУБД и это вообще не вопрос.

Ну а если нет, то хочу заметить, что если вопросы:
- удаление узла со всеми его дочерними элементами;
- переименование отдельного узла;
- применение маски при переименовании к узлу и его дочерним элементам;
- удаление узла со всеми его дочерними элементами.

Представляются мне решаемыми (и ответ на них можно найти по приведенной мною ссылке).
То вот задача "перезаписи" ключевых полей у меня и в голове не укладывается (собственно говоря как и то зачем это нужно smile ), возможно в этом сможет помочь кто-то более грамотный...

Дело в том, что для реализации задачи необходиомо обходить дерево строго сверу-вниз! Т.к. при случайном доступе к элементам мы рискуем изменить первичный ключ поля после того, как он уже был "учтен" запросом и был задан как код родительского элемента.

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

После необходимо создать копию исходной таблицы и добавить в неё поле для нового первичного ключа.

Затем в цикле необходимо для всех записей вызывать некую процедуру, которая бы в этой новой таблице последовательно перебирала записи сверху-вниз и ориентируясь по старому первичному ключу обновляла бы записи.

Всё это выглядет более чем сумбурно, но ничего более простого мне в голову не приходит...

Автор: Sed0Y 17.4.2010, 13:38
все - спасибо, решил проблему, создал темповую таблицу, туда все запихнул проабдейтил и выгрузил куда нужно smile

Код

SET SQL DIALECT 3;

CREATE GLOBAL TEMPORARY TABLE TREE (
    FID         INTEGER NOT NULL,
    FID_PARENT  INTEGER,
    FID_ORG     INTEGER,
    FCAPTION    VARCHAR(150),
    FTYPE       INTEGER
) ON COMMIT DELETE ROWS;

ALTER TABLE TREE ADD CONSTRAINT PK_TREE PRIMARY KEY (FID);
ALTER TABLE TREE ADD CONSTRAINT FK_TREE_1 FOREIGN KEY (FID_PARENT) REFERENCES TREE (FID) ON UPDATE CASCADE;


Код

SET SQL DIALECT 3;

CREATE GLOBAL TEMPORARY TABLE TEMP_TREE (
    FID         INTEGER NOT NULL,
    FID_PARENT  INTEGER,
    FID_ORG     INTEGER,
    FCAPTION    VARCHAR(150),
    FTYPE       INTEGER
) ON COMMIT DELETE ROWS;

ALTER TABLE TEMP_TREE ADD CONSTRAINT PK_TEMP_TREE PRIMARY KEY (FID);
ALTER TABLE TEMP_TREE ADD CONSTRAINT FK_TEMP_TREE_1 FOREIGN KEY (FID_PARENT) REFERENCES TEMP_TREE (FID) ON UPDATE CASCADE;


Код

SET TERM ^ ;

create or alter procedure "spUpdateTree"
as
begin
    insert into temp_tree select * from tree;
    update temp_tree set FID = GEN_ID(genid, 1);
    insert into "tbOrgTree" select * from temp_tree;
end^

SET TERM ; ^

GRANT ALL ON TEMP_TREE TO PROCEDURE "spUpdateTree";

GRANT ALL ON TREE TO PROCEDURE "spUpdateTree";

GRANT INSERT ON "tbOrgTree" TO PROCEDURE "spUpdateTree";

GRANT EXECUTE ON PROCEDURE "spUpdateTree" TO SYSDBA;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)