Announcement

Collapse
No announcement yet.

Stored Procedure aufrufen

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

  • Stored Procedure aufrufen

    Hallo,

    ich brauche dringend Hilfe - bin am Verzweifeln.

    Ich habe eine Stored Procedure (MS-SQL):

    Code:
    CREATE PROCEDURE boxG0
       @reihe CHAR(1) OUTPUT
       , @spalte CHAR(1) OUTPUT
       , @ebene CHAR(1) OUTPUT
       , @fach1 CHAR(1) OUTPUT
       , @fach2 CHAR(1) OUTPUT
       AS
          BEGIN
             DECLARE @reiheG0 CHAR(1), @spalteG0 CHAR(1), @ebeneG0 CHAR(1), @fachG01 CHAR(1)
             DECLARE c_G0 CURSOR FOR
                SELECT reihe, spalte, ebene, fach FROM la_platz WHERE mgl_g0 = '1' AND belegt = '0' AND reserv = '0'
             OPEN c_G0
             FETCH c_G0 INTO @reiheG0, @spalteG0, @ebeneG0, @fachG01         
             GOTO Schleife;         
          END
          
    	  Schleife:
          IF(@fachG01 = '1')
             BEGIN            
                DECLARE @belegt1 BIT, @reserviert1 BIT
                DECLARE c_G0fach2_1 CURSOR FOR
                   SELECT belegt, reserv FROM la_platz WHERE reihe = @reiheG0 AND spalte = @spalteG0 AND ebene = @ebeneG0 AND fach = '2'
                OPEN c_G0fach2_1
                FETCH c_G0fach2_1 INTO @belegt1, @reserviert1            
                IF(@belegt1 = '0' AND @reserviert1 = '0')
                BEGIN
                   SET @fach1 = '1'
                   SET @fach2 = '2'
                   CLOSE c_G0fach2_1
    			   DEALLOCATE c_G0fach2_1
                   GOTO Ende;
                END
                ELSE
    				CLOSE c_G0fach2_1
    				DEALLOCATE c_G0fach2_1
    				GOTO Weiter;
                
             END
             IF(@fachG01 = '3')
             BEGIN            
                DECLARE @belegt3 BIT, @reserviert3 BIT
                DECLARE c_G0fach2_3 CURSOR FOR
                   SELECT belegt, reserv FROM la_platz WHERE reihe = @reiheG0 AND spalte = @spalteG0 AND ebene = @ebeneG0 AND fach = '4'
                OPEN c_G0fach2_3
                FETCH c_G0fach2_3 INTO @belegt3, @reserviert3            
                IF(@belegt3 = '0' AND @reserviert3 = '0')
                BEGIN
                   SET @fach1 = '3'
                   SET @fach2 = '4'
                   CLOSE c_G0fach2_3
    			   DEALLOCATE c_G0fach2_3
                   GOTO Ende;
                END
                ELSE
    				CLOSE c_G0fach2_3
    				DEALLOCATE c_G0fach2_3
    				GOTO Weiter;
                
             END
             
             Weiter:
    			FETCH NEXT FROM c_G0 INTO @reiheG0, @spalteG0, @ebeneG0, @fachG01
    			GOTO Schleife;
    			
    		 Ende:
    			SET @reihe = @reiheG0;
    			SET @spalte = @spalteG0;
    			SET @ebene = @ebeneG0;
    			CLOSE c_G0
    			DEALLOCATE c_G0
          
       GO
       DECLARE @reiheG0 CHAR(1), @spalteG0 CHAR(1), @ebeneG0 CHAR(1), @fachG01 CHAR(1), @fachG02 CHAR(1)
       EXECUTE boxG0 @reiheG0 OUTPUT, @spalteG0 OUTPUT, @ebeneG0 OUTPUT, @fachG01 OUTPUT, @fachG02 OUTPUT
       SELECT @reiheG0, @spalteG0, @ebeneG0, @fachG01, @fachG02   
    --DROP PROCEDURE boxG0
    Wie kann ich mir das Ergebnis in Java anzeigen lassen?
    Dazu hab ich bisher folgendes:

    Code:
    try{
    				CallableStatement callG0 = Frame.cn.prepareCall("{call boxG0(?, ?, ?, ?, ?)}");
    				callG0.registerOutParameter(1, Types.CHAR);
    				callG0.registerOutParameter(2, Types.CHAR);
    				callG0.registerOutParameter(3, Types.CHAR);
    				callG0.registerOutParameter(4, Types.CHAR);
    				callG0.registerOutParameter(5, Types.CHAR);
    				Frame.rs = callG0.executeQuery();
    				if(Frame.rs.next()){
    					reiheG01 = Frame.rs.getString(1);
    					spalteG01 = Frame.rs.getString(2);
    					ebeneG01 = Frame.rs.getString(3);
    					fachG01 = Frame.rs.getString(4);
    					fachG02 = Frame.rs.getString(5);
    					System.out.println(reiheG01 + spalteG01 + ebeneG01 + fachG01 + fachG02);
    				}
    			}catch(Exception ex){
    				System.out.println("Keine Verbindung: " + ex);
    			}
    Die Datenbankverbindung steht - "normale" Abfragen hab ich auch schon ausgeführt, aber die Stored Procedure bringt mich an den Rand der Verzweiflung.

  • #2
    Was ist die Frage? Was für ein Fehler tritt auf? Wozu die {} im Statement?
    Christian

    Comment


    • #3
      Die {} hab ich mir aus verschiedenen Quellen rausgelesen, wenn die SP vorhanden ist, scheint sie ja auch gefunden zu werden, aber die Fehlermeldung ist die, dass kein ResultSet zurückgegeben wird, was aber nicht sein kann, da es Ergebnisse gibt.

      Nun hab ich auch ein mehr oder weniger kleines Verständnisproblem:
      Rein theoretisch ist mir klar, dass die SP erst mal über "create" hergestellt werden muss, damit sie gefunden werden kann. Aber ich muss die doch auch wieder löschen, um das nächste Ergebnis geliefert zu bekommen bzw. die SP erneut aufrufen zu können? Aber andererseits soll der Inhalt der SP ja immer wieder aufrufbar sein.
      Ich kann das schlecht erklären.

      Ich möchte wissen, wie ich die SP so wie sie ist, oder auch mit Veränderungen, in Java aufrufen kann und mir Ergebnisse geliefert werden.
      Es müsste folgendes Ergebnis rauskommen:
      @reiheG0 = A
      @spalteG0 = 1
      @ebeneG0 = B
      @fachG01 = 1
      @fachG02 = 2

      Comment


      • #4
        Die {} hab ich mir aus verschiedenen Quellen rausgelesen,
        Ein Blick in die Doku hätte ausgereicht.

        aber die Fehlermeldung ist die, dass kein ResultSet zurückgegeben wird, was aber nicht sein kann, da es Ergebnisse gibt.
        Mag sein, aber zum einen hat eine Procedure im Gegensatz zu einer Function keinen return Wert und zum anderen würde eine Stored Function die ein ResultSet zurückliefert ganz anders aussehen.

        Code:
        callG0.executeQuery()
        Du führst keine Abfrage aus, sondern startest ein Programm in der Datenbank. Daher musst Du execute aufrufen.

        Den Rückagewert deiner Variablen bekommst Du so:
        Code:
        reiheG01 = callG0.getString(1)
        Aber ich muss die doch auch wieder löschen, um das nächste Ergebnis geliefert zu bekommen bzw. die SP erneut aufrufen zu können? Aber andererseits soll der Inhalt der SP ja immer wieder aufrufbar sein.
        Wie kommst Du denn da drauf, dass Du sie löschen musst?

        Dim

        PS: Was um alles in der Welt hat dich dazu bewogen eine public, statische Klassenvariable zu verwenden? Wo ist da der Sinn drinnen?
        Zitat Tom Kyte:
        I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

        Comment


        • #5
          Hallo Dimitri,

          danke, danke, danke

          Es funktioniert.

          Ich habe die Variablen public deklariert, weil ich die auch in anderen Klassen noch brauche - ist das falsch?
          Ich muss dazu sagen, dass ich mir das alles, also Java und Datenbanken, in den letzten Wochen im Praktikum selbst irgendwie beigebracht habe. Deshalb bin ich dankbar für jede Anregung, Kritik und/oder Hilfe.

          Comment


          • #6
            Ich habe die Variablen public deklariert, weil ich die auch in anderen Klassen noch brauche - ist das falsch?
            Üblicherweise nutzt man dazu Getter / Setter Methoden
            Christian

            Comment


            • #7
              Hm, ok, das muss ich mir noch ansehen. Danke

              Comment


              • #8
                Des weiteren werden temporär verwendete Objekte auch nur temporär angelegt.
                Ein ResultSet als Instance- oder noch schlimmer als Klassenvariable anzulegen macht keinen Sinn, da Du nie den Status des Objektes weißt. Es könnte z.B. geschlossen sein (was auch Sinn macht um Ressourcen wieder freizugeben) etc.

                Es spricht nichts dagegen eine Abfrage wie folgt zu machen (ungetestet ):
                Code:
                void myQuery()
                {
                 Prepared Statement pstmt=null;
                 ResultSet rs=null;
                 try
                 {
                  pstmt=myConnection.prepareStatement("select col1 from tab where col2=?");
                  pstmt.setString(1,"Hugo");
                  rs=pstmt.executeQuery();
                  while(rs.next())
                  {
                   //Mach was mit den Daten
                  }
                 }
                 catch(SQLException e)
                 {
                 //Fehlerbehandlung
                 }
                 finally
                 {
                 try
                 {
                 if(pstmt!=null) 
                  pstmt.close();
                 }
                 catch(SQLException e)
                 {} //Hier auftretende Fehler können evtl. noch weggelogt werden, aber wir wollten das Statement eh loswerden.  
                 }
                }
                Es macht auch durchaus Sinn, sich eine eigene Methode zu bauen, die nichts anderes macht als ein übergebenes Statement Object zu schließen. Die wird dann anstelle des obigen Codes im finally Block aufgerufen.

                Wenn Du ein ResultSet weiterverwenden möchtest, dann gib es als return Wert an den Aufrufer der Funktion (natürlich ohne es vorher zu schließen - aufräumen muss dann natürlich der Aufrufer) - speichere es aber nicht als Klassen- oder Instancevariablen.

                Das Verwenden von normalen Statements anstelle eines PreparedStatement oder CallableStatement ist übrigends ein potentieller Bug, Sicherheitslücke und Performancekiller.

                Dim
                Zuletzt editiert von dimitri; 14.01.2009, 22:02.
                Zitat Tom Kyte:
                I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

                Comment


                • #9
                  Das werde ich mir mal genauer ansehen und den Code überarbeiten.
                  Ich habe sonst auch überall das PreparedStatement benutzt.

                  Comment

                  Working...
                  X