Announcement

Collapse
No announcement yet.

SQL-Anweisung in gespeicherter Prozedur aufbauen und ausführen.

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

  • SQL-Anweisung in gespeicherter Prozedur aufbauen und ausführen.

    Hallo Entwickler!

    Ich habe ein Problem beim erstellen einer gespeicherten Prozedur.

    Undzwar geht es darum, dass zum Beispiel ein Kunde in einer Datenbank geändert werden soll. Nehmen wir an, dieser hat die Spalten Kundennr, Name und Vorname.

    Nun soll das mit einer gespeicherten Prozedur passieren, die als Parameter diese Inofrmationen erhält. Wenn eine Variable "NULL" ist, soll sie unverändert bleiben.

    Ich möchte nun in der Prozedur mit Cases eine SQL Abfrage "aufbauen" und in einem TEXT speichern.
    Das soll dann so aussehen, dass via Insert einem bestehenden Text eine Zeichenkette angehangen wird. Diese soll sich wiederrum aus "AND" und dem Inhalt eines Prameters zusammensetzen. Im Grunde möchte ich hier, was eigentlich in Java gemacht wird, vollständig in die Prozedur auslagern. In Java würde das ja dann so aussehen: query = query + "AND" + name;
    Wäre dies möglich?

    Und kann ich dann innerhalb der Prozedur die Query, die im TEXT-Datenfeld gespeichert wurde, ausführen?

    Ich würde mich sehr über Vorschläge freuen!

    Gruß, Kunio
    Zuletzt editiert von kunnio; 22.08.2011, 19:42.

  • #2
    Hallo,
    Originally posted by kunnio View Post
    ...würde das ja dann so aussehen: query = query + "AND" + name;
    Wäre dies möglich?
    Prinzipiell Ja, aber so nicht. Strings können in MySQL nicht mit dem Plus-Operator (+) verknüpft werden. Dazu muss die Funktion CONCAT verwendet werden.
    Originally posted by kunnio View Post
    ...
    Und kann ich dann innerhalb der Prozedur die Query, die im TEXT-Datenfeld gespeichert wurde, ausführen?
    Ja, das ist mit Prepared Statements möglich.

    Gruß Falk
    Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

    Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

    Comment


    • #3
      Hallo, zunächst erst Mal danke für deine rasche Antwort.

      Mit CONCAT könnte ich also die Query mit IFS nach und nach aufbauen, je nachdem welche Parameter geändert werden sollen.

      Bei Prepared statements ist es aber so (so wie ich das verstanden habe), dass man eine SQL-Query schreibt, wo "?" als Parameter stehen. Wenn ich jetzt jedoch nur den Vornamen eines Kunden ändern möchte, dann würden die restlichen Parameter im Prepared Statement unausgefüllt bleiben. Diese könnte dann doch so nicht ausgeführt werden, oder?

      Außerdem steht in der Dokumentation:
      SQL syntax for prepared statements can be used within stored procedures, but not in stored functions or triggers.
      Das würde doch bedeuten, dass ich keine Ergebnistabellen zurückgeben kann, oder? Dieses muss aber gegeben sein.

      Comment


      • #4
        Originally posted by kunnio View Post
        ...Bei Prepared statements ist es aber so (so wie ich das verstanden habe), dass man eine SQL-Query schreibt, wo "?" als Parameter stehen.
        Das ist ein Vorteil von Prepared Statements, aber kein Dogma. Du bist ja nicht gezwungen Parameter zu verwenden, würde sich aber trotzdem anbieten, auch wenn du deinen SQL-String dynamisch zusammenbaust.
        Originally posted by kunnio View Post
        ...Außerdem steht in der Dokumentation:...
        Du hast von einer "gespeicherten Prozedur" gesprochen. Von einer Funktion oder einem Trigger war bisher nicht die Rede! Wenn du Nebenbedingungen nicht nennst, kann ich die ja schlecht erraten .

        Gruß Falk
        Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

        Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

        Comment


        • #5
          Sollte auch kein Vorwurf oderso sein

          Aber noch Mal fürs Verstehen: Kann ich also dem prepared statement mit CONCAT() weitere Zeichenketten hinzufügen, und diesen dann mit Excecute ausführen?

          Gibt es keine andere Möglichkeit, eine Abfrage, die in einem String gespeichert ist, auszuführen, sodass ich Ergebnistabellen liefern kann? Oder habe ich das falsch verstanden und eine Abfrage in einer Prozedur gibt ganz normal eine Tabelle aus?

          Gruß

          Comment


          • #6
            So richtig weiss ich nicht was du willst! Bisher sprachst du davon Datensätze zu ändern. Das geschieht mit einem UPDATE-Statement, welches kein Resultset als Ergebnis hat und folglich auch nichts ausgeben kann.

            Was spricht denn konkret gegen Prepared Statements? Du solltest dein Problem etwas klarer (und ggfs. ausführlicher) schildern, ansonsten kann dir auch niemand konkret helfen!

            Beispiel:
            [highlight=sql]
            set @stmt =
            'UPDATE personen SET
            PersName = IFNULL(?, PersName),
            PersID = IFNULL(?, PersID)
            WHERE PersID = ?';

            PREPARE dynStmt FROM @stmt;

            /* Beispiel 1 */
            EXECUTE dynStmt USING null, 99, 1;

            /* Beispiel 2 */
            EXECUTE dynStmt USING 'Person99', null, 99;

            /* Beispiel 3 */
            EXECUTE dynStmt USING 'Person88', 88, 2;
            [/highlight]

            Gruß Falk
            Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

            Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

            Comment


            • #7
              Tut mir Leid, ich bin noch ein Neuling in diesem Gebiet, und war etwas durcheinander, ich versuche meine Fragen nun etwas präziser zu stellen.

              Am Anfang ging es tatsächlich nur darum, den Kunden zu ändern. Dafür brauche ich nichts zurückgeben.

              Wenn ich nun aber eine ähnliche Funktion schreiben soll, die ebenso dynamisch sein, aber eine Tabelle mit Suchergebnissen ausgeben soll, kann ich das mit einer Prozedur machen, oder brauche ich dafür eine Funktion?
              Also konkret: Der Kunde besteht aus Kundennr, Name und Vorname. Meiner Prozedur wird nur der Vor- und Nachname übergeben, nicht aber die Kundennr. Z.B.: Ich suche nach allen "Hans Meier" in meiner Kundendb. Ich erhalte eine Tabelle mit 20 Kunden, die Hans Meier heißen, aber natürlich unterschiedliche Kundennummern haben.
              Das wäre dann ja eine simple Select-Abfrage.


              Originally posted by Falk Prüfer View Post

              Beispiel:
              [highlight=sql]
              set @stmt =
              'UPDATE personen SET
              PersName = IFNULL(?, PersName),
              PersID = IFNULL(?, PersID)
              WHERE PersID = ?';

              PREPARE dynStmt FROM @stmt;

              /* Beispiel 1 */
              EXECUTE dynStmt USING null, 99, 1;

              /* Beispiel 2 */
              EXECUTE dynStmt USING 'Person99', null, 99;

              /* Beispiel 3 */
              EXECUTE dynStmt USING 'Person88', 88, 2;
              [/highlight]

              Gruß Falk
              Danke für Dein Beispiel und Deine Mühe. Bei Beispiel 1 würde also folgende Abfrage ausgeführt werden?


              'UPDATE personen SET
              PersName = PersName,
              PersID = 99,
              WHERE PersID = 1';


              Du hast mich bis jetzt auf jeden Fall schon ein ganzes Stück weitergebracht! Ich hoffe meine Fragen sind jetzt nachvollziehbarer.

              Comment


              • #8
                Originally posted by kunnio View Post
                ...Wenn ich nun aber eine ähnliche Funktion schreiben soll, die ebenso dynamisch sein, aber eine Tabelle mit Suchergebnissen ausgeben soll, kann ich das mit einer Prozedur machen, oder brauche ich dafür eine Funktion?
                Das kommt ganz darauf an, wie die Anwendung mit der du die Statements ausführst damit umgehen kann. Ein explizites Select innerhalb einer Prozedur erzeugt genauso wie ein per EXECUTE ausgeführtes Prepared Statement ein Resultset. Was die Anwendung damit macht liegt nicht im Ermessen von MySQL!

                Die MySQL-Kommandozeile erzeugt bei beiden Beispielen die erwartete Ausgabe:

                [highlight=sql]
                delimiter |

                create procedure test1()
                begin
                select 'Hallo' Test;
                end;
                |

                create procedure test2()
                begin
                set @stmt = 'select ? Test';
                set @var = 'auch Hallo';

                PREPARE dynStmt FROM @stmt;
                EXECUTE dynStmt USING @var;
                end;
                |

                delimiter ;
                [/highlight]
                [highlight=sql]
                call test1;
                [/highlight]
                +-------+
                | Test |
                +-------+
                | Hallo |
                +-------+
                1 row in set (0.00 sec)

                [highlight=sql]
                call test2;
                [/highlight]
                +------------+
                | Test |
                +------------+
                | auch Hallo |
                +------------+
                1 row in set (0.00 sec)


                Originally posted by kunnio View Post
                ...Danke für Dein Beispiel und Deine Mühe. Bei Beispiel 1 würde also folgende Abfrage ausgeführt werden?


                'UPDATE personen SET
                PersName = PersName,
                PersID = 99,
                WHERE PersID = 1';
                Ja!

                Gruß Falk
                Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

                Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

                Comment


                • #9
                  Das hört sich sehr gut an. Die Prozeduren sollen mit Javaprogrammen aufgerufen werden. Die Tabellen könnte man dann ja in einem ResultSet speichern, richtig?

                  Comment


                  • #10
                    Originally posted by kunnio View Post
                    Die Tabellen könnte man dann ja in einem ResultSet speichern, richtig?
                    Nein! Bitte bring nicht die Begrifflichkeiten durcheinander! Wenn wir hier im Rahmnen von Datenbanken von Tabellen reden, dann sind das für mich Objekte die in der DB gespeichert und "irgendwie" vom SQL-Server verwaltet werden. Diese haben nichts mit anderen (HTML-, Excel-, ...) "Ausgabe"-Tabellen zu tun!

                    Gruß Falk
                    Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

                    Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

                    Comment


                    • #11
                      Wie kann ich dann die Ergebnistabelle, die innerhalb einer Prozedur entstanden ist (das, was die SELECT-Abfrage der Kundentabelle liefern würde), in Java weiterverarbeiten?
                      Ich dachte, man kann ganz normal die Prozedur via Java aufrufen, anstatt eine SQL-Abfrage an den Server zu senden, und die Antwort im ResultSet abspeichern?

                      Comment


                      • #12
                        Was dir Java in Bezug auf den Aufruf gespeicherter Prozeduren bietet, kann ich dir nicht sagen. Das ist dann wohl eher eine Frage fürs Java-Forum und hat ja nur noch mittelbar was mit MySQL zu tun.

                        Gruß Falk
                        Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

                        Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

                        Comment


                        • #13
                          Ok Falk, ich möchte mich noch ein Mal bei Dir bedanken.
                          Gruß

                          Comment


                          • #14
                            Hallo,

                            ich habe nun auf diese Weise eine andere Prozedur geschrieben, die aber nicht funktionieren möchte! Es ist so, dass folgender Code immer den gesamten Tabelleninhalt anzeigt! Was mache ich falsch? Wenn ich statt param einen konkreten Wert angebe, bekomme ich einen Syntaxfehler, aber ich kann ihn nicht finden.

                            Code:
                            Delimiter //
                            CREATE PROCEDURE test(param varchar(10))
                            BEGIN
                            SET @stmt = "Select * FROM tabelle Where Spalte1 = IFNULL(?, Spalte1);";
                            PREPARE dynstmt FROM @stmt;
                            Execute dynstmt USING @param;
                            END//
                            Delimiter ;
                            Gruß,
                            Kunnio
                            Zuletzt editiert von kunnio; 06.09.2011, 12:34.

                            Comment


                            • #15
                              Hallo,

                              Prepared Statements können nur mit Servervariablen umgehen. Du musst also der Servervariable @param noch den Wert des lokalen Parameters param zuweisen. (siehe Zeile 4)
                              [highlight=sql]
                              CREATE PROCEDURE testsuche(param varchar(10))
                              BEGIN
                              SET @stmt = "Select * FROM tabelle Where Spalte1 = IFNULL(?, Spalte1)";
                              SET @param = param;
                              PREPARE dynstmt FROM @stmt;
                              Execute dynstmt USING @param;
                              END//
                              [/highlight]

                              Anmerkung: Das Semikolon ist innerhalb der SQL-Anweisung überflüssig bzw. eigentlich sogar falsch. Dies wird nur in Konsolenumgebungen als Kommandotrenner benötigt.

                              Gruß Falk
                              Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

                              Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

                              Comment

                              Working...
                              X