Ankündigung

Einklappen
Keine Ankündigung bisher.

Stored Procedure mit Parameter innerhalb einer Schleife

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Stored Procedure mit Parameter innerhalb einer Schleife

    Hallo,

    ich habe mir für meine Datenbank-Abfragen eine Klasse gebaut, die automatisch den Verbindungsauf- und abbau regelt,
    Sql-Statements ausführt und Datenfelder für HTML aufbereitet. Klappt gut.
    Sobald ich allerdings statt eines umfangreichen SELECTs eine Stored Procedure per CALL aufrufe, wird's ungemütlich.
    Mit einer SP geht's noch, spätestens bei der zweiten kommen Fehler wie
    'Commands out of sync; you can't run this command now' oder
    'Warning: Packets out of order. Expected 1 received x'.
    Gut, man muss Resultsets freigeben, das verstehe ich noch.
    Das muss man beim Verwenden von SELECT-Statements zwar nicht machen, aber auch gut.
    Noch komplizierter wird es bei parametrisierten Procedures.
    Und leider gibt's dazu nur dürftige Erläuterungen im Netz.
    (Ich erwarte jetzt auch nicht mehr, alles in einer allgemeinen Klasse abzuhandeln,
    da es gerade mit Parametern deutlich komplexer werden kann.)

    Hier eine praktisches Beispiel:
    Ich habe eine Tabelle mit Sportvereinen und eine mit Sportarten und dazwischen
    eine Kreuztabelle für die Sportarten, die in den einzelnen Vereinen angeboten werden.
    (Einige Vereine bieten viele Sportarten an, die meisten nur eine und u.U. sogar keine.)

    Ich habe zwei SPs, eine zum Lesen der Vereinsdaten und die zweite zum Lesen der Sportarten anhand der Vereinsnummer.
    Ich stelle mir das schematisch etwa so vor:

    PHP-Code:
    // $conn1 = Verbindung zur MySQL-DB (via mysqli)
    // $conn2 = 2. Verbindung - für die 2. SP (geht wohl nicht mit einer Connection)

    $stmt1 $conn1->prepare('CALL lesen_vereinsdaten');
    $stmt1->execute();
    $result1 $stmt1->get_result();

    $stmt2->$conn2->prepare('CALL lesen_sportarten_im_verein(?)');
    $stmt2->bind_param('i'$nr_verein);

    while (
    $data1 $result1->fetch_row())) {
    $nr_verein $data1[0];
    ....

    $stmt2->execute();
    $result2 $stmt2->get_result();
    while (
    $data2 $result2->fetch_row()) {
    $sportart $data[0];
    ...
    }

    $stmt2->free_result();


    Offensichtlich kommen die SPs der 2. Ebene sich ins Gehege.
    Beim 2. execute() kommt es zu Meldungen 'Packets out of order'
    oder die Ergebnisse sind schlicht falsch.

    Ich habe hier schon viele Varianten ausprobiert,
    z.B. bind_param innerhalb der while-Schleife,
    leider alle ohne Erfolg.

    Hat jemand ein wirklich funktionierendes Beispiel?

    Übrigens läuft's ohne SPs, also mit SELECT-Statements, wunderbar.
    Warum nicht mit SPs?

    Besten Dank
    Klaus
    Grüße aus Köln am Rhein
    Klaus Trapp
    [url]www.trappdata.de[/url]

  • #2
    Daten in Whileschleifen zu holen, das tut meistens keine Not.
    Stored Procedures tun oft auch keine Not (wenngleich man LandAufLandAb glaubt, es sei das schnellste, was man machen kann).
    Stored Procedures erlauben es dann leider noch, eine Menge Dinge zu implementieren, die es nicht besser machen (plus möglichst noch manuelle Transaktionsschubserei).
    Da kann am Ende schon mal was über die Klinge springen.

    Ist aber alles nur geraten, weil weder Deine Select Statements noch Dein SP Code bekannt ist.
    Was hat er, was sie nicht hat? (Er, der SP Code und sie, die SQL)

    Kommentar


    • #3
      Immer wieder nett, Antworten auf Fragen zu bekommen, die man nicht gestellt hat,
      weit davon entfernt, das zu erfahren, was man wissen will.
      Wenn ich über die Problematik von Stored Procedures hätte diskutieren wollen,
      was hinlänglich an anderer Stelle nachzulesen ist,
      hätte die Frage vermutlich gelautet, was denn besser wäre, SPs oder SQL-Statements.
      Meine Frage richtete sich aber erkennbar nach dem Wie-geht-es.
      Muss man z.B. bind_param in die Schleife setzten, ist stmt->free_result() aureichend,
      sollte man bind_result einsetzen o.ä.
      Dies zu lösen, scheint aber ein erhebliches Problem zu sein.

      Wie die SQL-Statements aussehen, kann man sich bei der Simplizität des Beispiels eigentlich denken:
      einfache SELECT-Feldliste-From, im 2. Fall mit variabler Vereinsnummer in der WHERE-Klausel
      und das Gleiche dann einfach mit CREATE PROCEDURE als SP verpackt.
      (Nebenebei bemerkt: Unter phpMyAdmin laufen die SPs natürlich korrekt.)
      Grüße aus Köln am Rhein
      Klaus Trapp
      [url]www.trappdata.de[/url]

      Kommentar


      • #4
        Jeweils nach get_result() noch ein next_result() ausführen. Du bekommst zwei "Resultsets" zurück, wenn du ein SP aufrufst mit einem SELECT ohne INTO. Das erste Resultset ist das des SELECTS, das zweite "Resultset" ist die Bestätigung, dass die SP ausgeführt wurde.

        Kommentar


        • #5
          Aus dem Handbuch zu PHP.
          Please note, that not every MYSQL server version may support preparing the CALL SQL statement.
          Leider wird nicht angegeben, welche Versionen betroffen sind, aber vielleicht liegt es ja da dran.
          Ansonsten den Beispielen aus dem Handbuch folgen.
          Und aussedem muss
          PHP-Code:
            $db->setAttribute(PDO::ATTR_EMULATE_PREPAREStrue); 
          gesetzt sein.

          Kommentar


          • #6
            Zitat von erc Beitrag anzeigen
            Jeweils nach get_result() noch ein next_result() ausführen.
            Genau das hat mir gefehlt. Besten Dank, erc
            Grüße aus Köln am Rhein
            Klaus Trapp
            [url]www.trappdata.de[/url]

            Kommentar

            Lädt...
            X