Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Запрос на SQL для выборки иерархического списка [MSSQL]


Страницы:   1 2 3

SuperChel ©   (2008-06-19 22:19:00) 

Приветствую Вас Мастера.
Есть простая таблица и для простоты пример: у таблицы два поля id и id_roditel в id храниться уникальное значение, а в id_roditel храниться ссылка на поле id. Как вы уже поняли это связный иерархический список. Хочу выбрать всю ветку потомков, указав какой то конкретный узел. Наведите на мысль как составить такой sql запрос.


stas   (2008-06-20 17:05:00) [1]

Вот функция которая это все делает, думаю разберетесь.
Основная таблица называется SOSTZAK
ALTER FUNCTION [dbo].[FSOSTZAKUP](@NOMZP as int )
RETURNS
@TAB TABLE (IDNOMZ INT IDENTITY (1,1) NOT NULL,
                        GLZAP    INT,          
                        NOMZAP INT,
                        UROVEN INT
 
           primary key (IDNOMZ)  )   --Создание временной таблицы

AS
BEGIN
DECLARE @MAXID INT,
                 @PMAXID INT,
                 @I INT

INSERT INTO @TAB (GLZAP, NOMZAP, UROVEN)
           SELECT SOSTZAK.NOMZAP, SOSTZAK.NOZP, 0
           FROM SOSTZAK with(nolock)
          WHERE NOMZAP=@NOMZP     --Занесение во временную таблицу записи из SOSTZAK

SET @I=1                       --уровень
SET @PMAXID=0--(SELECT MAX(IDNOMZ) FROM @TAB)--1         --предыдущий максимальный ID
SET @MAXID=(SELECT MAX(IDNOMZ) FROM @TAB)            --максимальный ID

WHILE @PMAXID<>@MAXID AND @I<10  --максимальный уровень (защита от зацикливания)


BEGIN

INSERT INTO @TAB (GLZAP, NOMZAP, UROVEN)
           SELECT SOSTZAK.GLZAP, SZAK.NOZP, @I
           FROM @TAB SOSTZAK INNER JOIN SOSTZAK SZAK with(nolock) ON SOSTZAK.NOMZAP=SZAK.NOMZAP
           WHERE IDNOMZ>@PMAXID    --Присоединение таблицы SOSTZAK

SET @I=@I+1
SET @PMAXID=@MAXID
SET @MAXID=@@identity

END

RETURN
END


stas   (2008-06-20 17:02:00) [2]

b z   (20.06.08 16:52) [56]
Таблица
IDZ
GLZAP - PARETNTID
NOMZAP - ID

Цель таблицы отобразить всех детей каждого родителя.

Триггер на INSERT основной таблицы:
В эту таблицу пакетная вставка данных непредумотрена

SET @NZAP = (SELECT NOMZAP FROM INSERTED )
INSERT INTO FSOSTZAKA (GLZAP,NOMZAP)
SELECT GLZAP, NOMZAP FROM FSOSTZAKUP (@NZAP)
FSOSTZAKUP (@NZAP)  - функция в цикле достает всех родителей этой записи


stas   (2008-06-20 16:55:00) [3]

Ega23 ©   (20.06.08 16:51) [55]
Ну, в принципе можно, только это будет тоже самое что я предложил только вместо цикла который в multi statement функции будет рекурсия.


b z   (2008-06-20 16:52:00) [4]


> stas ©   (20.06.08 16:45) [54]

Таблиц, с тригерами надеюсь будет само-собой ... :)


Ega23   (2008-06-20 16:51:00) [5]


> Результат функции - набор данных, как мне ее вызвать внутри
> самой себя?
>


А что такого?


stas   (2008-06-20 16:45:00) [6]

b z   (20.06.08 16:39) [52]
Структуру таблиц? или привести и триггеры?


stas   (2008-06-20 16:39:00) [7]

Ega23 ©   (20.06.08 16:37) [51]
Результат функции - набор данных, как мне ее вызвать внутри самой себя?


b z   (2008-06-20 16:39:00) [8]


> 2. Это наполнение постоянной таблицы триггерами.
Покажите, пож-ста, пример структуры для "дерева", основанный на этом варианте.


Ega23   (2008-06-20 16:37:00) [9]


> (вобще я непредставляю как можно сделать рекурсивную функцию


А что такого?


stas   (2008-06-20 16:32:00) [10]

Ega23 ©   (20.06.08 16:22) [48]
Ну не нужен он в этой функции.
Я вот непонимаю что вы пытаетесь оспорить
я предлагаю 2 варианта

1. Это функция без всякой рекурсии (вобще я непредставляю как можно сделать рекурсивную функцию) Которая по перечисленым выше параметрам превосходит хранимку
2. Это наполнение постоянной таблицы триггерами.

2-й вариант на выборке довольно шустрый. И с введением именно 2-го варианта у себя в деревьях серверу на много полегчало.
А какой вариант выбирать автору это уже его дело.


stas   (2008-06-20 16:25:00) [11]

MsGuns ©   (20.06.08 16:12) [47]
1. Вы сами противоречите себе, я рассказывал что это делается функцией и что у функции есть  приимущество перед хранимкой...
2. Вы не вызовите хранимку из функции в MS SQL
3. Мне ваш код ненужен т.к. у меня есть свой и ненужен мне ваш готовый код у меня их целая куча, и быстрее и правильнее нет  я по крайней мере не находил.


Ega23   (2008-06-20 16:22:00) [12]


> Ну это же не простой способ. функцию проще объеденить.


В функции динамический SQL низя использовать.


MsGuns   (2008-06-20 16:12:00) [13]

>stas ©   (20.06.08 16:00) [44]
>вы заблуждаетесь, велосипед изобретаете вы,

Я уже приводил выше откуда можно взять готовый алгоритм. Если Вам действительно это интересно, потрудитесь ее найти, почитать указанную главу и разобраться.

>к тому же вы не ответили на мой вопрос по поводу простого решения объединения >результатов хп с другой таблицей.

Из фунции можно вызвать ХП и ее результат связать с любым другим запросом, хранимкой или функцией. Напишите нужную Вам функцию на сервере и с клиента будете писать простой запрос Select from функция

>и что вы называете обычным велосипедом?

Стандартный механизм рекурсии, упомянутый в [1], который Вас почему-то вообще не заинтересовал.
Вы хотите, чтобы я дал Вам готовый универсальный код ? Я его не дам по двум причинам. Во-первых такого кода не существует из-за особенностей скл-серверов, о чем Вам тут неоднократно сообщалось. А во-вторых, учитесь не брать готовое, а искать в указанных Вам направлениях.

Не сем тему обсуждения считаю исчерпанной


stas   (2008-06-20 16:06:00) [14]

Ega23 ©   (20.06.08 16:04) [45]
Ну это же не простой способ. функцию проще объеденить.


Ega23   (2008-06-20 16:04:00) [15]


> к тому же вы не ответили на мой вопрос по поводу простого
> решения объединения результатов хп с другой таблицей.


А что такого? В MSSQL только один способ есть :

ctreate table #xxx (....)

Insert into #xxx  exec c_proc

Select ..... from
 Table T1 inner join #xxx X on (T... = X....)


stas   (2008-06-20 16:00:00) [16]

MsGuns ©   (20.06.08 15:50) [43]
изобретенный Велосипед? вы заблуждаетесь, велосипед изобретаете вы, к тому же вы не ответили на мой вопрос по поводу простого решения объединения результатов хп с другой таблицей.
и что вы называете обычным велосипедом?


MsGuns   (2008-06-20 15:50:00) [17]

>stas ©   (20.06.08 15:07) [42]
>Ну, сдесь можно долго спорить.

О чем спорить ? Что изобретенный Вами велосипед с двумя рулями и треугольными колесами лучше обычного ?
Сервер "тормозил" не от отсутствия "статичной" таблицы, а из-за кривизны алгоритма, который здесь не обсуждается.
Есои Вы полагаете, что наличие триггеров "ускоряет" работу сервера с таблицей, то Вы сильно заблуждаетесь, особенно если эти самые триггеры еще что-то куда-то вставляют.


stas   (2008-06-20 15:07:00) [18]

MsGuns ©   (20.06.08 14:39) [41]
Ну, сдесь можно долго спорить.
У меня было построение дерева с помощью функции и есть статичная таблица, которая наполняется триггерами, серверу значительно полегчало.


MsGuns   (2008-06-20 14:39:00) [19]

>stas ©   (20.06.08 13:07) [39]
>Сколько пользователей юзает одновременно эти деревья?

Пользователи не "юзают деревья" по той простой причине, что этих деревьев на сервере нетути. Они строятся на клиенте по датасету, полученному с сервера в рез-те разузловки. После выполнения ХП сервер передает НД клиенту и благополучно о нем "забывает". Поэтому можно вести речь только о взможной конкуренции РАСЧЕТОВ.
Однако влияние этой конкуренции малозаметно, т.к. сервер выполняют еще массу другой работы, да и баз данных на сервере не одна и даже не 10.


Anatoly Podgoretsky   (2008-06-20 13:23:00) [20]

> stas  (20.06.2008 13:07:39)  [39]

А тебе зачем, разве это чтото дает в понимании. Неинтересная это информация.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо