2013-04-19 10 views
6

Przykład danych:składowanych SQL procedury, gdy pętla

ID Name  ParentID 
1 parent-1 NULL 
2 parent-2 NULL 
3 sub  1 
4 child-1-1 3 
5 child-1-2 1 
6 child-2-1 2 

Teraz Gdybym szukać nazwisk jak '% Rodziny z 1%', chcę następujące rekordy: Rząd-1, wiersz 3, Hałas -4 i wiersz-5 w powyższych danych. Jakiego rodzaju, jeśli procedura przechowywana może napisać, że zwraca mi niewyraźne wiersze?

Mój pomysł jest taki, że jeśli wyszukuję tekst, będzie on nadal wybierać rekordy z tabeli, dopóki identyfikator parentID nie będzie mieć wartości NULL. Więc jeśli zrobię coś w rodzaju wyszukiwania "child-1", podstawowe zapytanie sql zwraca Row-4 i Row-5. Ale moja procedura sprawdzania shud w pętli, że Row-4 ma parentid, który nie jest pusty, więc dostaje wiersz z identyfikatorem = parentid z wiersza-4, który jest 3. Teraz dostaje wiersz z identyfikatorem = parentid wiersza-3, który jest 1 i dostaje wiersz-1. Teraz parentd z rzędu -1 ma wartość NULL, więc przestaje.

Używam tej procedury przechowywanej do implementacji funkcji wyszukiwania w widoku drzewa, w którym chcę zachować hierarchię nadrzędny podrzędność po wyszukiwaniu.

tej pory próbowałem tego, ale jestem nowym do procedur przechowywanych:

USE DBname 
Go 
DECLARE @ParentID int 
Declare @myresultset Cursor 
Set @myresultset = CURSOR for Select ParentID from mytable where Name like 'child-1%' 
OPEN @myresultset 
Fetch NEXT from @myresultset 
into @ParentID 
While @@Fetch_Status=0 
Begin 
While @ParentID is not NULL 
    Begin 
    Select @ParentID = ParentID from mytable where [email protected] 
    Select distinct * from mytable where [email protected] 
    End 
Fetch Next from @myresultset 
into @ParentID 
End 
close @myresultset 

Odpowiedz

4

Zamiast kodowania to za pomocą kodu proceduralnego, ja recoded to za pomocą zorientowanych zestaw SQL. Używam rekurencyjnego CTE, aby znaleźć "rodziców" danych dzieci. Oto mój procedura przechowywana:

CREATE PROC find_parents (@childname varchar(20)) as 

;WITH heirarchy_cte (ID, Name, ParentID, Level) as 
(SELECT e.ID, e.Name, e.ParentID, 0 as Level 
    FROM mytable as e 
    where e.Name like @childname 
UNION ALL 
SELECT e.ID, e.Name, e.ParentID, Level+1 
    FROM mytable as e 
    INNER JOIN heirarchy_cte as h 
    ON h.ParentID=e.ID 
    ) 
SELECT DISTINCT ID, Name, ParentID 
FROM heirarchy_cte 
ORDER BY ID 

I następnie uruchomić go z:

exec find_parents @childname='child-1%' 

Jeśli moje wyniki są prawidłowe, to rozwiązanie powinno skalować lepsze dla większej ilości danych. Zakodowałem również to jako procedurę przechowywaną, jak wskazałeś.

Aby zobaczyć pełny kod, zobacz SQL Fiddle w: Find Parents SQL Fiddle Demo

Jeżeli moje rozwiązanie jest poprawne, należy oznaczyć go jako odpowiedź. Dzięki.

+0

Thanks Michael Harmon..Thanks kodu. Działa idealnie. Jeszcze raz dziękuję za pomoc. – user2272865

0

Spróbuj tego prostego przykładu

CREATE PROCEDURE proc (
    IN i INTEGER, 
    IN j INTEGER) 
BEGIN 
    DECLARE z integer; 
    set z=i; 
    while (z<j) do 
    begin 
     set z=z+1; 
    end; 
    end while; 
END;