Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.03.10;
Скачать: CL | DM;

Вниз

Как вызвать в процедуре саму себя?   Найти похожие ветки 

 
Кило   (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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.023 c
7-30162
pfar
2002-11-27 07:32
2003.03.10
Опрос модема


3-29767
Наташа
2003-02-19 17:18
2003.03.10
проект


1-29838
V-Isa
2003-02-28 11:45
2003.03.10
Определение компонента, над которым расположен курсор мыши


3-29720
NightCold
2003-02-18 12:12
2003.03.10
СРОЧНО!


1-29797
Gonta
2003-02-27 17:51
2003.03.10
Работа с консольными приложениями