Форум: "Базы";
Текущий архив: 2003.03.10;
Скачать: [xml.tar.bz2];
ВнизКак вызвать в процедуре саму себя? Найти похожие ветки
← →
Кило (2003-02-18 15:18) [0]Мастера, помогите.
CREATE PROCEDURE GETPATHTOROOT (
id_parent INTEGER)
RETURNS (
name varchar(1000))
AS
DECLARE VARIABLE parent integer;
DECLARE VARIABLE child integer;
BEGIN
select name_operation, child_cnt, parent_id
from type_operation
where id_operation=:id_parent
into :name, :child, :parent;
if (:child=0) then
name = name + getpathtoroot(parent);
else
exit;
suspend;
END
Ругается, что нет getpathtoroot
← →
Wolf (2003-02-18 15:34) [1]Надо создать данную процедуру с пустым телом, а затем выполнить alter.
set term ^;
CREATE PROCEDURE GETPATHTOROOT (
id_parent INTEGER)
RETURNS (
name varchar(1000))
AS
BEGIN
suspend;
END^
alter PROCEDURE GETPATHTOROOT (
id_parent INTEGER)
RETURNS (
name varchar(1000))
AS
DECLARE VARIABLE parent integer;
DECLARE VARIABLE child integer;
BEGIN
select name_operation, child_cnt, parent_id
from type_operation
where id_operation=:id_parent
into :name, :child, :parent;
if (:child=0) then
name = name + getpathtoroot(parent);
else
exit;
suspend;
END^
← →
Johnmen (2003-02-18 15:51) [2]Еще бы неплохо глянуть в хелп по поводу вызова ХП.
← →
Кило (2003-02-18 15:54) [3]Я как раз его и смотрю( www.codenet.ru/db/interbase), а там такого нет...
← →
Wolf (2003-02-18 15:59) [4]Блин, а я и не заметил, что вызов процедуры неправильно написан, скопировал и все.
Тогда меняешь
if (:child=0) then
name = name + getpathtoroot(parent);
на
if (:child=0) then
select :name||name from getpathtoroot(:parent)
into :name;
← →
Wolf (2003-02-18 16:08) [5]Можно и так
alter PROCEDURE GETPATHTOROOT (
id_parent INTEGER)
RETURNS (
name varchar(1000))
AS
DECLARE VARIABLE parent integer;
DECLARE VARIABLE child integer;
DECLARE VARIABLE t_name varchar(1000);
BEGIN
select name_operation, child_cnt, parent_id
from type_operation
where id_operation=:id_parent
into :name, :child, :parent;
if (:child=0) then
begin
execute procedure getpathtoroot(:parent)
returning_values(:t_name)
name = name||t_name;
end
else
exit;
suspend;
END
← →
Wolf (2003-02-18 16:15) [6]Кстати, ты кажись напутал чего-то
if (:child=0) then
begin
execute procedure getpathtoroot(:parent)
returning_values(:t_name)
name = name||t_name;
end
else
exit;
suspend;
по моему надо так.
if (:parent=0) then
begin
execute procedure getpathtoroot(:parent)
returning_values(:t_name)
name = name||t_name;
end
suspend;
1. Ты идешь от конца до начала ветки, а начало, там где parent=0,
если он у тебя null - то поправь мое условие на:parent=null
или что там у тебя.
2. твойelse exit;
приведет к тому, что вызывать процедуру сможешь только черезexecute procedure
, аselect from
- не пройдет.
← →
Кило (2003-02-18 16:19) [7]2 wolf
Я уже по другому делаю через while и без рекурсии
А на счет ошибки ты прав, там я напутал... Ну учусь я только
Спасибо за то что помогаешь..
← →
Johnmen (2003-02-18 16:22) [8]>Кило
А просто глянуть в SQL Reference Help ? :)))
← →
Кило (2003-02-18 16:26) [9]А это где? :) я не нашел...
← →
Johnmen (2003-02-18 16:36) [10]Пуск->Программы->InterBase->Documentation->SQL Reference Help
Примерно там............
← →
Wolf (2003-02-18 16:38) [11]C FB его нет. C IB есть.
У делал такую задачу:
Тоже нужен полный путь, но только от указанного элемента, всех "детей", "внуков", "правнуков" и т.д.
Вот там без рекурсии не обойтись.
Советую для тренировки сделать такую процедуру.
← →
Кило (2003-02-18 16:58) [12]
> Вот там без рекурсии не обойтись.
Почему? вроде можно...
← →
Wolf (2003-02-18 17:06) [13]Попробуй :)
Ты должен получить такой список
У Цех №1 и Цех №2 - есть родитель, который и есть тот исходный элемент.
Цех №1
Цех №1 / Участок №1
Цех №1 / Участок №1 / Блок А
Цех №1 / Участок №1 / Блок Б
Цех №1 / Участок №2
Цех №2
Цех №2 / Блок Р
← →
Кило (2003-02-18 17:11) [14]Пример из http://www.ibase.ru/devinfo/treedb.htm CREATE
PROCEDURE GETPARENTS (ID INTEGER)
RETURNS (DID INTEGER, OID INTEGER, NAME VARCHAR(30))
AS
BEGIN
WHILE (:ID > 0) DO /* ищем до корня */
BEGIN
SELECT O.ID, O.PARENT, O.NAME
FROM OBJECTS O
WHERE O.ID = :ID
INTO :DID, :OID, :NAME;
ID = :OID; /* код родителя для следующей выборки */
SUSPEND;
END
END
← →
Val (2003-02-18 17:19) [15]>Wolf © (18.02.03 17:06)
Попробуй :)..
Кило (18.02.03 17:11)
Пример из...
лихо, а? ;)
не то, что некоторые, даже f1 нажать лень.
← →
Кило (2003-02-18 17:22) [16]некоторым просто нужно обьяснить, что и как, а не кидаться с репликами типа: мы тут самые умные, а ты дурак и иди и смотри туда(f1, www... и т.д.)
← →
Val (2003-02-18 17:38) [17]>Кило (18.02.03 17:22)
вы, уважаемый, вероятно, не поняли смысла моего поста, посему зря нервничаете.
← →
Wolf (2003-02-18 18:20) [18]Да, это почти то что тебе надо, единственно, вместо suspend, нужно выполнять конкатенциюб у них немного другое условие задачи.
То же и в моей задаче, только надо выполнить перебор всех элементов.
Но я думаю рекурсия будет оптимальней. Счас попробую проверить.
← →
Wolf (2003-02-18 18:34) [19]Да, но откуда мне знать какие элементы выбирать? Какие принадлежат этому куску дерева. Все-таки нужна рекурсия.
вот мой вариант
CREATE PROCEDURE test_tree(
AID_DEPARTMENT INTEGER,
ANAME_DEPARTMENT VARCHAR(512))
RETURNS (
ID_DEPARTMENT INTEGER,
NAME_DEPARTMENT VARCHAR(512))
AS
declare variable tid_department integer;
declare variable child integer;
declare variable tname_department varchar(512);
begin
for
select d.id, d.name, d.child from rf_department d
where d.parent=:aid_department
into :tid_department, :tname_department,:child
do
begin
if (aname_department is not null)
then tname_department=aname_department||"."||tname_department;
name_department=tname_department;
id_department=tid_department;
suspend;
if (child>0) then
for select id_department, name_department
from test_tree(:tid_department,:tname_department)
into :id_department, :name_department
do
suspend;
end
END
Кстати без поля child можно и обойтись, но если оно есть, то можно и возпользоваться, чтобы лишний раз не выполнять select
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.03.10;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.01 c