Rekursive Funktionen in SQL-Azure
Für den Fall, das man eine Kategorie-Struktur nach dem Child-Parent Prinzip abfragen möchte bietet sich manchmal eine rekursive Funktion an.
Das folgende Beispiel soll den Aufbau erklären:
CREATE TABLE [dbo].[kategorien]( [uid] [bigint] IDENTITY(1,1) NOT NULL, [pid] [bigint] NOT NULL, [Name] [nvarchar](100) NOT NULL, [Tstamp] [datetime] NULL CONSTRAINT [PK_kategorien] PRIMARY KEY CLUSTERED ([uid] ASC) )
im Beispiel ist die „uid“ der Primärschlüssel der Kategorie, pid ist der Fremdschlüssel auf das Elternobjekt.
Zum besseren Verständnis sollen einige Datensätze hinzugefügt werden:
INSERT INTO kategorien (pid,Name,Tstamp) VALUES (0,'Root Kategorie',getDate()); INSERT INTO kategorien (pid,Name,Tstamp) VALUES (1,'Erste Unterkategorie',getDate()); INSERT INTO kategorien (pid,Name,Tstamp) VALUES (1,'Zweite Unterkategorie',getDate()); INSERT INTO kategorien (pid,Name,Tstamp) VALUES (2,'Kategorie unter Erster Unterkategorie',getDate());
Möchte ich nun zum Beispiel die uids der Unterkategorien abfragen verwende ich folgende Funktion:
CREATE FUNCTION [dbo].[selectUnterKategorien_2] (@Einstieg int) RETURNS NVARCHAR(MAX) AS BEGIN DECLARE @ret NVARCHAR(MAX)= CONVERT(VARCHAR(MAX), @Einstieg); DECLARE @uid int; DECLARE mycursor CURSOR LOCAL FOR SELECT [uid] FROM [dbo].[kategorien] WHERE pid = @Einstieg BEGIN OPEN mycursor; FETCH NEXT FROM mycursor INTO @uid; WHILE @@fetch_status = 0 BEGIN SET @ret = @ret +',' + dbo.selectUnterKategorien_2(@uid); FETCH NEXT FROM mycursor INTO @uid; END CLOSE mycursor; DEALLOCATE mycursor; RETURN @ret; END END
noch kurz getestet:
Voila, eine Liste der Kategorie mit ihren Unterkategorien.