2013-04-19 3 views
6

esempio di dati:stored procedure SQL ciclo while

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 

ora se cerco nome simile a '% bambino-1%', voglio che i seguenti record: Riga-1, riga-3, Fila -4 e riga 5 nei dati sopra. Che tipo di procedura memorizzata posso scrivere che mi restituisce righe discrete?

La mia idea è Se cerco un testo, continuerà a selezionare i record dalla tabella fino a quando il parentID è nullo. Quindi, se faccio una ricerca simile a "child-1", una query sql di base restituisce Row-4 e Row-5. Ma il mio shud di procedura controlla in un loop che Row-4 ha parentid che non è nullo, quindi ottiene una riga con ID = parentid di row-4 che è 3. Ora ottiene una riga con ID = parentid di row-3 che è 1 e ottiene la riga-1. Ora padre della riga-1 è NULL, quindi si ferma.

Sto utilizzando questa procedura memorizzata per implementare una funzionalità di ricerca nella vista ad albero in cui voglio mantenere la gerarchia padre-figlio dopo la ricerca.

Finora ho provato questo, ma io sono nuovo a stored procedure:

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 

risposta

4

Invece di codifica questo usando codice procedurale, ho ricodificati questo utilizzando set orientato SQL. Sto usando un CTE ricorsivo per trovare i "genitori" dei bambini dati. Ecco la mia procedura immagazzinata:

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 

Ho poi eseguirlo con:

exec find_parents @childname='child-1%' 

Se i miei risultati sono corretti, allora questa soluzione dovrebbe scala di meglio per una maggiore quantità di dati. L'ho anche codificato come procedura memorizzata come avevi indicato.

per vedere il codice completo, vedere il violino SQL a: Find Parents SQL Fiddle Demo

Se la mia soluzione è corretta, si prega di contrassegnare come la risposta. Grazie.

+0

Grazie Michael Harmon..Thanks per il codice. Funziona perfettamente. Grazie ancora per l'aiuto. – user2272865

0

Prova questo semplice esempio

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;