Sequa: Besondere SQL Query

Hallo Zusammen,

ich hatte das vor ein paar Tagen schonmal gefragt, bekam aber keine Antwort... daher hoffe ich das mir jetzt jemand helfen kann (vielleicht wurde das erste Posting auch überlesen...)

Also, folgender Code besteht:

my (@qp,@qq,@qe) = ("");
foreach (@{$conf->{rg}->{ext_data}}) {push (@qq,"?",",");}
foreach (@{$conf->{rg}->{ext_data}}) {push (@qp,"$_",",");}
foreach (@{$conf->{rg}->{ext_data}}) {push (@qe,"$input->{$_}",",");}
pop @qq;
pop @qp;
pop @qe;

my $sth = $dbh->prepare(" INSERT INTO $iconf->{dbt}->{ext_data} (id_key,@qp) VALUES (?,@qq) ");
$sth->execute($max_id,@qe);

---

natürlich besteht eine DB Verdinung und die Arrays sind korrekt gefüllt (hab das auch testweise ausgeben lassen).

nun zum Problem...
@qp und @qq werden so interpretiert das die darin befindlichen Werte anstelle der @qp bzw. @qq Arrays gesehen werdn... bei @qp sind das die spaltennamen mit kommas, bei @qq sind das die Fragezeichen.
Das funktioniert also... @qe hingegen wird als eine einzige Variable gesehen, was dann natürlich zu einem Fehler führt (execute called with 2 bind variables when 8 are needed)

ich hab auch schon versucht das mit referenzen auf die Arrays das zu ändern... hatte aber den gleichen Effekt...

nun meine Frage dazu... wie bekomme ich das so hin das es funktioniert... es ist sehr wichtig das die spaltennamen sowie die fragezeichung und dann halt auch der content vollkommen variablen sind...

Ich hoffe das mir da jemand helfen kann...

Schonmal danke, Sequa

  1. Hallo,

    Gehen wir es der Reihe nach durch:

    my (@qp,@qq,@qe) = ("");

    @qp  hat jetz ein Element, @qq,@qe jeweil null. ISt das so gewollt? Ich denke nicht.
    my (@qp,@qq,@qe);
    reicht vollkommen. Da es jetzt leichter beim Lesen wäre, den Dingern  aussagekräftigere Namen zu geben.

    foreach (@{$conf->{rg}->{ext_data}}) {push (@qq,"?",",");}
    foreach (@{$conf->{rg}->{ext_data}}) {push (@qp,"$_",",");}
    foreach (@{$conf->{rg}->{ext_data}}) {push (@qe,"$input->{$_}",",");}

    Wozu drei Schleifen, wenn sowieso immer über das gleiche Array iteriert wird?
    Aber dazu später.
    Nemen wir uns vorher

    my $sth = $dbh->prepare(" INSERT INTO $iconf->{dbt}->{ext_data} (id_key,@qp) VALUES (?,@qq) ");
    $sth->execute($max_id,@qe);

    vor.
    Das $iconf könnte ein Tippfehlersein, aber auch nicht, kann ich nicht sagen, wolle es nur erwähnen.

    Der erste Punkt ist mal:

    $sth->execute();

    das erwartet beispielsweise
    $sth->execute(1,2,3,4,5,6,7,8,...);
    Also einfach einel Liste von Werten oder eben ein Array von werten. Du hast aber

    foreach (@{$conf->{rg}->{ext_data}}) {push (@qe,"$input->{$_}",",");}

    geschrieben, daraus wird also ($max_id ist angenommen 1)
    $sth->execute(1,'$input->{FELDNAME1}','$input->{FELDNAME2}',....);
    wobei zu bemerken ist, daß Du also nicht die Werte aus dem Formular wiederfindest, sondern eben den Text '$input->{FELDNAME1}' im zweiten Feld. Also wirklich so wie es hier geschrieben ist.
    Der Grund ist, daß Du mit dem \ das $ ausmaskiert hast, Perl also nicht auf den Inhalt des Hashes, dessen Referenz in $input liegt, zugreift. Ui klingt das jetzt kompliziert.

    Das ist der eigentliche Grund, warum es nicht funktioniert.

    Dann möchte ich jetzt noch kurz auf noch etwas eingehen, bevor ich zur fertigen Sache komme.
    Da gibt es die Funktion join, die Du Dir ansehen solltest.
    Beispiel:

    my(@array) = (1,2,3,4);
    my $text = join(' trennzeichen ',@array);
    jetzt steht in $text
    '1 trennzeichen 2 trennzeichen 3 trennzeichen 4'
    Es wird also aus dem Array ein Scalar gemacht, wobei zwischen den einzelnen Elementen ein beliebiger Text eingefügt werden kann.

    Du könntest also:

    my (@fieldnames, @placeholders, @values);

    foreach (@{$conf->{rg}->{ext_data}})
       {
       push @placeholders,'?';
       push @fieldnames,'$_';
       push @values,"$input->{$_}";
       }
    my $fields = join(',',@fieldnames);
    my $placeholders = join(',',@placeholders);

    my $sth = $dbh->prepare("INSERT INTO $iconf->{dbt}->{ext_data} (id_key,$fields VALUES (?,$placeholders)");
    $sth->execute($max_id,@values);

    schreiben.
    Da gibts sicherlich noch einiges zu optimieren, wie etwa der Einsatz von map, aber kommt Zeit kommt map:-)

    Grüße
      Klaus

    So,