Rekursive Abfrage in SP nach XML umformen und per VARCHAR(MAX) OUTPUT ausgeben...

Einfach nur um den Faden zu behalten:
(PL/SQL-Syntax... Allerdings mit Notepad geschrieben, hab gerade keinen Editor zur verfügung)
Code:
Create Function recursive_tree
(
id In Number
) Return Varchar2 Is
   Cursor get_current_level(p_id_ Number) Is
    Select n.nodeid
          ,n.nodetext
    From   nodes n
    Where  n.parentnodeid = coalesce(p_id_, 0);

   v_node_id_ get_current_level.nodeid%Type;
   v_node_text_ get_current_level.nodetext%Type;

   v_return_ Varchar2(4000);
Begin
   Open get_current_level(id);
   Loop
   Fetch get_current_level Into v_note_id_, v_note_text_;
   Exit When get_current_level%NotFound;

   v_return_ := v_return_ || v_node_text_ || recursive_tree(v_node_id_);
   End Loop;
   Close get_current_level;
End;
Es gibt keine Möglichkeit so eine Funktion in T-SQL zu schreiben?

Das sähe dann glaube ich so aus: (Oder zumindest so ähnlich? :( )
Code:
CREATE FUNCTION dbo.sp_showTreeByRecursion
   @parentNodeID INT = NULL
RETURN VARCHAR AS
BEGIN
DECLARE @nodeID     INT,
    @nodeText   VARCHAR(32),
    @tempVar    VARCHAR(MAX)

DECLARE Nodes_Cursor CURSOR LOCAL FOR
   SELECT  NodeID,
       NodeText
   FROM Nodes
   WHERE ISNULL(ParentNodeID, 0) = ISNULL(@parentNodeID, 0) AND ParentNodeID IS NOT NULL
   ORDER BY NodeText ASC

SET @tempVar = ''

OPEN Nodes_Cursor
FETCH NEXT FROM Nodes_Cursor INTO @nodeID, @nodeText
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC @tempVar = @tempVar + @nodeText + sp_showTreeByRecursion (@nodeID) + ' '

FETCH NEXT FROM Nodes_Cursor INTO @nodeID, @nodeText
END
RETURN @tempVar
END

Würde mich doch sehr verwundern wenn so etwas nicht unterstützt wird...
 
Werbung:
Hallo Distrilec

Das hat soweit gut geklappt mit ein paar kleineren T-SQL-spezifischen Anpassungen, welche ich noch vornehmen musste.
UDF's sind für meinen Fall wohl eher angebracht, denn damit kann man, im Ggs. zu SP's, alles zurückgeben. (Bei SQL Server SP's nur INT-Werte, um den Status zurückzugeben. Argument Variable "By Reference" (=OUTPUT) wäre wohl ne Möglichkeit trotzdem was zu übergeben, aber für mein Fall ist eine UDF definitiv besser!

Vielen Dank!!!


Gruss, Jan
 
Zuletzt bearbeitet von einem Moderator:
Werbung:
Nun sieht es so aus, die Zeile wo die Funktion sich selbst aufruft musste ich ein wenig anders gestalten wegen der String-Concatenation:

(Evtl. kennen die T-SQL-Experten einen eleganteren Weg als extra ne Variable "@ret" einzusetzen??)


Code:
USE test
  GO

IF EXISTS (SELECT ('') FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[sp_showTreeByRecursion2]') AND TYPE IN (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
  DROP FUNCTION [dbo].[sp_showTreeByRecursion2]
END
  GO

CREATE FUNCTION dbo.sp_showTreeByRecursion2(@parentNodeID INT = NULL)
RETURNS VARCHAR(MAX) AS
BEGIN
  DECLARE
      @nodeID   INT,
    @nodeText VARCHAR(32),
    @tempVar  VARCHAR(MAX),
      @ret          VARCHAR(MAX)
 
  DECLARE Nodes_Cursor CURSOR LOCAL FOR
    SELECT
          NodeID,
          NodeText
    FROM Nodes
    WHERE ISNULL(ParentNodeID, 0) = ISNULL(@parentNodeID, 0) AND ParentNodeID IS NOT NULL
    ORDER BY NodeText ASC
   
    SET @tempVar = ''
   
    OPEN Nodes_Cursor
    FETCH NEXT FROM Nodes_Cursor INTO @nodeID, @nodeText
    WHILE @@FETCH_STATUS = 0
    BEGIN
      IF (SELECT COUNT ('') FROM Nodes WHERE ParentNodeID = @nodeID) > 0
      BEGIN
        SET @tempVar = @tempVar  + '<entry value="' + @nodeText + '">'
        EXEC @ret = sp_showTreeByRecursion2 @nodeID
          SET @tempVar = @tempVar + @ret
          SET @tempVar = @tempVar + '</entry>'
        END
      ELSE
      BEGIN
          SET @tempVar = @tempVar + '<entry value="' + @nodeText + '" />'
      END
      FETCH NEXT FROM Nodes_Cursor INTO @nodeID, @nodeText
    END
  RETURN @tempVar
END


Das gibt dann folgendes zurück (in unformatiertem zustand natürlich):

HTML:
<entry value="Kleidung">
  <entry value="Damenkleidung" />
  <entry value="Herrenkleidung" />
</entry>
<entry value="Lebensmittel">
  <entry value="Gemüse">
    <entry value="Broccoli" />
    <entry value="Kohlrabi" />
  </entry>
  <entry value="Getränke" />
  <entry value="Obst">
    <entry value="Orangen" />
    <entry value="Pfirsich" />
  </entry></entry>

Noch weniger overhead hätte man mit json...
 
Zurück
Oben