Announcement

Collapse
No announcement yet.

Alle Selects aus Cursorschleife zusammenpacken

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Alle Selects aus Cursorschleife zusammenpacken

    Hallo Leute!

    Habe seit kurzem begonnen mich mit T-SQL und Stored Procedures zu beschäftigen. Ich verusche z.zT. eine Prozedur zu schreiben, die anhand verschiedener Kriterien ([</>/=] , datum, User_ID) Einträge aus einer Tabelle auslesen soll. Dies geschieht indem ich, ganz trivial, erstmal jedes Datum in der Tabelle anhand der [</>/=] und dem übergebenen Datum hole. Danach durchlaufe ich die ERgebnisse und prüfe zu welcher User_ID der entsprechende Eintrag gehört. Nun Gut! Eigentlich funktioniert das auch alles, nur bekomme ich eben für jeden gefundenen Eintrag eine SELECT-Ausgabe! Damit kommt meine Anwendung nicht zurecht und ich erhalte eben nur einen Eintrag in meiner Auflistung.

    Nun zu meiner eigentlichen Frage: Gibt es eine möglichkeit die SELECT's irgendwie zusammenzufassen? Könnte ja alles in ein Array packen, aber wie kann ich dieses dann identisch wie eine SELECT-Abfrage ausgeben lassen? Kann doch eigentlich garnicht so schwer sein. Bei so einer verzwickten Fragestellung googelt man sich da aber einen an die klatsche.

    Hier mal noch der Surce:

    Code:
    alter procedure searchAkquiseNachhakenSonstige
    @criteria varchar(2),
    @datum datetime,
    @tbl_User_ID As int
    AS
    
    -- START: CHECK THE CRITERIA FOR THE SELECTION
    
    	IF @criteria = '<'
    		DECLARE adressen_cursor CURSOR FOR
    		SELECT ID,tbl_User_ID FROM tbl_Adressen WHERE AkquiseNachhaken < @datum
    	ELSE IF @criteria = '='
    		DECLARE adressen_cursor CURSOR FOR
    		SELECT ID,tbl_User_ID FROM tbl_Adressen WHERE AkquiseNachhaken = @datum
    	ELSE IF @criteria = '>'
    		DECLARE adressen_cursor CURSOR FOR
    		SELECT ID,tbl_User_ID FROM tbl_Adressen WHERE AkquiseNachhaken > @datum
    	ELSE
    		DECLARE adressen_cursor CURSOR FOR
    		SELECT ID,tbl_User_ID FROM tbl_Adressen WHERE 1 = 2
    -- END
    	DECLARE @varLongString as varchar
    	OPEN adressen_cursor
    	DECLARE @varID int,@varUserID int
    		FETCH NEXT FROM adressen_cursor INTO @varID, @varUserID -- WRITE THE VALUES INTO THE VARIABLES
    			
    			WHILE(@@FETCH_STATUS <> - 1) -- NOT FAILED, OR CURSOR AT IT'S END
    				BEGIN
    					
    					IF(@@FETCH_STATUS <> - 2) -- ROW NOT MISSING
    					
    						IF @tbl_User_ID = - 1 -- DON'T CARE ABOUT THE USER ID!
    							SELECT * FROM tbl_Adressen WHERE ID = @varID
    						ELSE
    							SELECT * FROM tbl_Adressen WHERE ID = @varID AND tbl_User_ID = @varUserID
    		
    			FETCH NEXT FROM adressen_cursor INTO @varID, @varUserID
    				END
    	CLOSE adressen_cursor
    DEALLOCATE adressen_Cursor
    Gruß Sebbi
    Zuletzt editiert von Sebischn; 24.05.2007, 14:50.

  • #2
    Hallo,

    die Frage, ob für diese Aufgabenstellung ein CURSOR die richtige Wahl ist, blende ich erst einmal aus.

    Gibt es eine möglichkeit die SELECT's irgendwie zusammenzufassen?
    ja, es muss dazu nur eine TABLE-Variable deklariert werden. Die CURSOR-Schleife legt alle einzelnen Datensätze dann in der TABLE-Variable ab. Am Ende werden dann über SELECT * FROM @TableVariable alle Datensätze als Ergebnismenge an den Aufrufer zurückgeliefert.

    Das folgende Beispiel demonstriert das Prinzip:

    Code:
    DECLARE @TmpTbl TABLE (kdnnr INT NOT NULL, mails NVARCHAR(MAX));
    DECLARE @kdnnr INT;
    DECLARE @last INT;
    DECLARE @mail NVARCHAR(99);
    DECLARE @liste NVARCHAR(MAX);
    SET @liste = '';
    DECLARE @CursorVariable CURSOR; 
    SET @CursorVariable = CURSOR LOCAL FAST_FORWARD FOR 
      SELECT kdnnr,mail FROM TestTbl ORDER BY kdnnr; 
    OPEN @CursorVariable; 
    FETCH NEXT FROM @CursorVariable INTO @kdnnr, @mail;
    SELECT @last = @kdnnr;
    WHILE (@@FETCH_STATUS=0)  
      BEGIN 
        IF @kdnnr <> @last
          BEGIN
            INSERT INTO @TmpTbl VALUES (@last, @liste); 
            SET @last = @kdnnr;
            SET @liste = '';
          END
        SELECT @liste = @liste + @mail + '; ' 
        FETCH NEXT FROM @CursorVariable INTO @kdnnr, @mail 
      END 
    IF @last IS NOT NULL
      INSERT INTO @TmpTbl VALUES (@last, @liste);
    CLOSE @CursorVariable 
    DEALLOCATE @CursorVariable 
    -- Ergebnis anzeigen
    SELECT * FROM @TmpTbl

    Comment


    • #3
      Hi Andreas!

      Danke für deine Antwort! War genau, was ich suchte. Hat wunderbar funktioniert.

      Hast Du vielleicht noch eine Idee, was ich gegen diesen redundanten Code am Anfang tun könnte?

      IF @criteria = '<'
      DECLARE adressen_cursor CURSOR FOR
      SELECT ID,tbl_User_ID FROM tbl_Adressen WHERE AkquiseNachhaken < @datum
      ELSE IF @criteria = '='
      DECLARE adressen_cursor CURSOR FOR
      SELECT ID,tbl_User_ID FROM tbl_Adressen WHERE AkquiseNachhaken = @datum
      ELSE IF @criteria = '>'
      DECLARE adressen_cursor CURSOR FOR
      SELECT ID,tbl_User_ID FROM tbl_Adressen WHERE AkquiseNachhaken > @datum
      Das gefällt mir irgendwie garnicht! Werde in Zukunft noch öfters in die Situation gelangen Operationen zu programmieren, welche solche Theta-operatoren nutzen.

      Wird doch für sowas sicherlich irgendwie eine schönere Lösung geben. Für kleine Abfragen wie diese geht sowas ja noch klar, aber falls sich mal unter einem IF ein großes Stück Code verbirgt lässt das 1. den Code aufquellen und 2. schleichen sich möglicherweisse Fehler ein, weil man übersieht den Code der anderen ( Ich nenne sie mal Bruder/Schwester- ) Abfragen anzupassen.

      Gruß Sebbi

      Comment

      Working...
      X