Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как из функции дать сигнал наружу? / 11 сообщений из 11, страница 1 из 1
10.10.2002, 18:39:36
    #32057223
Viktor Rybak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
MSSQL.
У меня есть хранимая процедура, ктр запускает функцию, которая может запускать себя, т.е. рекурсивная функция.
Вся эта конструкция иногда долго работает.
Хотелось бы как-то проанализировать ее в Query Analyser или путем записи марков времени во временную таблицу.

Но !!!

1) Print в ф. не работает!
2) Insert в ф. не работает!
3) хр. процедуру из ф. не вызвать!
4) Prifiler вызовы моей функции не показывает!

Посоветуйте, знатоки.
...
Рейтинг: 0 / 0
10.10.2002, 18:48:37
    #32057229
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
Мой совет: Не надо делать рекурсивные функции
...
Рейтинг: 0 / 0
11.10.2002, 10:22:39
    #32057361
Viktor Rybak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
Функция сканирует ветви деревьев и подсчитывает некую сумму по условию. Без рекурсии здесь не обойтись.

Впрочем, причем здесь рекурсия? См. сабж.
Подскажите, кто знает!
...
Рейтинг: 0 / 0
11.10.2002, 10:33:36
    #32057373
snake
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
/topic/10197
...
Рейтинг: 0 / 0
11.10.2002, 11:40:07
    #32057406
Viktor Rybak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
Спасибо за ссылку, там все прекрасно. Но у меня другая задача - здесь без рекурсивной функции не обойтись.

CREATE FUNCTION dbo.fTimeParentAlloc_sub (@ParentId as int)
RETURNS int AS
BEGIN
--if @@NESTLEVEL > 20 return 0
declare @Sum as int
set @Sum = 0

select @Sum = sum(case when ms.MSType < 2 then ms.TimePlan else dbo.fTimeParentAlloc_sub(ms.ID) end)
FROM ms
WHERE ms.MSParent = @ParentId

return ISNULL(@Sum, 0)
END
...
Рейтинг: 0 / 0
11.10.2002, 13:04:16
    #32057467
Garya
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
Вместо рекурсии можно делать псевдорекурсию на циклах. Собственно, настоящая рекурсия - это обыкновенный цикл с сохранением контента в стеке. Организуй себе что-то вроде стека и крути циклы. Работать будет гораздо шустрее, чем настоящая рекурсия. Хотя бы потому, что ты свой "стек" можешь организовать наиболее оптимальным образом - чтобы сохранялось в нем только то, что нужно, а не все подряд.
Функции имеют ограничения. И с этим приходится мириться. А кто тебя заставляет дедать все именно в виде функции? Почему не в виде SP? Кстати, они себя умеют рекурсивно вызывать...
...
Рейтинг: 0 / 0
11.10.2002, 14:36:15
    #32057528
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
Но у меня другая задача - здесь без рекурсивной функции не обойтись.

Интересно как же это я обошелся?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
set nocount on 

declare @ms table(id int, parent int, mstype int, timeplan int)
 /*
  1       4    1
    11    1    100
    12    4    1000  *
      123 4    10000
      124 1    100000*
    13    4    1000000
     131  1    10000000 *
*/ 
insert @ms select  1 ,  0 ,  4 ,     1 
insert @ms select  11 ,  1 ,  1 ,    100 
insert @ms select  12 ,  1 ,  4 ,    1000 
insert @ms select  123 ,  12 ,  4 ,  10000 
insert @ms select  124 ,  12 ,  1 ,  10000 
insert @ms select  13 ,  1 ,  4 ,    1000000 
insert @ms select  131 ,  13 ,  1 ,  10000000 

declare @id int
set @id= 1 
 -------------------------
 
declare @t table(id int, level int, tp int)
declare @lev int
set @lev= 0 

insert @t 
  select case when mstype <  2  then - 1  else id end, @lev, case when mstype <  2  then timeplan else  0  end
    from @ms
    where id=@id

while exists(select * from @t t, @ms ms where @lev=level and t.id=ms.parent)
  begin
	insert @t 
	  select case when mstype <  2  then - 1  else ms.id end, 
             @lev+ 1 , 
             case when mstype <  2  then timeplan else  0  end
	    from @ms ms, @t t
	    where t.id=ms.parent and level=@lev
    set @lev=@lev+ 1 
  end


select sum(tp) from @t

А если еще учесть что структура дерева может быть другой...

Так что мой предыдущий совет остаётся в силе :)
...
Рейтинг: 0 / 0
11.10.2002, 17:37:10
    #32057603
Viktor Rybak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
to SergSuper
Спасибо, это работает.
Ну раз мы тут собрались, тогда еще пара вопросов:
1) А что, Вы вообще против рекурсий в SQL?
2) Что Вы имеете ввиду, намекая на другую структуру дерева? У меня она двойная, т.е. классическая ( с указанием одной ссылки на Parent ) и с памятью всех родителей (10 уровней). Это как то влияет на приложение?
...
Рейтинг: 0 / 0
13.10.2002, 19:46:44
    #32057762
sparrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
Viktor Rybak
4) Prifiler вызовы моей функции не показывает!

???

У меня Prifiler показывает всё. Раскажи подробней про версии MSSql, Windows, Servis Packs
...
Рейтинг: 0 / 0
14.10.2002, 09:51:45
    #32057816
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
2 Viktor Rybak
1) Вообще вроде как в теории рекурсией лучше не пользоваться. С ней писать проще, но обычно алгоритмы с рекурсией менее эффективные. Т.е. рекурсию применяют обычно там где алгоритм без ней получается слишком сложным. Например когда есть косвенная рекурсия - процедура А, вызывает процедуру В, которая опять вызывает А.
Это всё что касалось процедурных языков. В SQL где можно очень просто хранить данные в таблицах, я вообще не вижу смысла ей пользоваться. К тому же и глубина её небольшая.

2)
Например есть тиакие идеи:
http://sdm.viptop.ru/articles/sqltrees.html
http://www.osp.ru/win2000/sql/967.htm
Не факт что это Вам подойдёт, но знать надо.
...
Рейтинг: 0 / 0
14.10.2002, 13:18:40
    #32057937
Viktor Rybak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как из функции дать сигнал наружу?
To SergSuper:
Спасибо за помощь!

To sparrow:
- Windows 2000 Prof (sp3)
- SQL Server 2000

Процедура с возвращаемым параметром вызывает рек-функцию. Profiler вызовы фукции не показывал, было лишь множество строк с процедурой с параметром NULL, затем с правильным ответом из функции.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как из функции дать сигнал наружу? / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]