(SQL server 2k) Återigen, jag är såååå tacksam för all hjälp jag får i detta forum... Det är inte bra med recursiva anrop i SQL Server. Finns dessutom en begränsning i hur mångha anrop du kan göra. ...såg att jag hade skrivit fel kod i min lösning, @name variabeln skall deklareras inuti if sattsen och inte likadant som jag gjorde där..:) Tack så mycket för lösningen skall jag tillägga:) Höll på att gömma tacka för hjälpen..:) Eftersom SQL är ett mängdbaserat språk så bör man försöka att skriva SQL-satser som opererar på hela mängder, inte procedurell kod som t ex jobbar rad-för-rad eller rekursivt. Det finns alternativa metoder till att hantera hierarkiska strukturer i SQL, t ex Joe Celkos metod Nested Sets. Jag tycker att http://www.sitepoint.com/article/hierarchical-data-database är bättre.rekursiv sql?
3 tabeller:
<code>
tblUsers
---------
usrIdent - uniqueidentifier (primary key)
...
---------
tblMemeberOf
---------
mboIdent - int (primary key) <-|
... |
mboParent - int ------------------| (allow nulls)
(dvs relation till mboIdent)
tblUsrMbo (junction)
---------
...
usrmboUser - int (relation till tblUsers.usrIdent)
usrmboMember - int (relation till tblMemberOf.mboIdent)
</code>
En relations kedja i denna herarki kan se ut som följande:
<code>
Elev-|
|-Inriktning-|
|-Programmering-|
|- Årskurs 3 -|
|- MinKlass
</code>
Då användarna kommer att bli members eller få en relation i junctiontabeln
till någon av noderna så vill jag att de skall kunna se den node de är medlemar
i, men även alla överliggande.
Ex 1:
Dvs är jag medlem i 'Programmering' vill jag få returnerat 'Programmering', 'inriktning 'samt 'elev'.
Ex 2:
Och är jag medlem i 'MinKlass' vill jag få ut hela den underliggande node kedjan.
Mycket tacksam för hjälp:)!Sv: rekursiv sql?
Återigen blev jag tvungen att lösa mitt problem själv.......
Frågor som jag fick besvarade igenom olika tester jag fick genomföra:
Kan en lagrad procedur kalla på sig själv? Svar: JA
Kod exempel:
<code>
if exists(select name from sysobjects where name='sp_GetMemberChain')
drop proc sp_GetMemberChain
go
create proc sp_GetMemberChain
@ParentIn int,
@ParentOut int output
as
declare @Name char(25)
select @ParentOut = tblMemberOf.mboParent from tblMemberOf where tblMemberOf.mboIdent = @ParentIn
if(@ParentOut is not null)
begin
exec sp_GetMemberChain @ParentOut,@ParentOut
end
select @Name = tblMemberOf.mboName from
tblMemberOf where tblMemberOf.mboIdent = @ParentOut
print @Name
go
</code>
Problem löst.Sv: rekursiv sql?
I ditt fall kan det undvikas:
<code>
If exists(select name from sysobjects where name='sp_GetMemberChain')
drop proc sp_GetMemberChain
go
CREATE PROC sp_GetMemberChain
@mboIdent int,
@usrIdent int
AS
DECLARE @Parent int
DECLARE @Name char(25)
SELECT @Parent = tblMemberOf.mboParent, @Name = tblMemberOf.mboName
FROM tblMemberOf
WHERE tblMemberOf.mboIdent = @mboIdent
WHILE (@Parent Is Not Null)
BEGIN
PRINT @Name
SET @mboIdent = @Parent
SET @Parent = Null
SELECT @Parent = tblMemberOf.mboParent, @Name = tblMemberOf.mboName
FROM tblMemberOf
WHERE tblMemberOf.mboIdent = @mboIdent
END
GO
</code>
Tror denna kommer vara effektivare eftersom den dessutom hämtar namnet i samma SQL sats som förälder.
Egentligen kanske man borde använda en deklarerad variabel än parametern @mboIdent i loopen. Sv: rekursiv sql?
Vad är det som gör rekursiva sp's i sql-server ineffektiva då? Vad är nackdelarna?Sv: rekursiv sql?
Sv: rekursiv sql?
Som Andreas sa är SQL Server dessutom begränsad till 32 nivåers rekursion.Sv:rekursiv sql?