Jan: Mehrere Bilder aus der DB aufeinmal löschen? (perl/mysql)

Hallo,

Ist es eigentlich möglich mehrere Bilder aus der Datenbank aufeinmal löschen?

Hab schon n paar Stunden im Forum und auch sonst überall nachgeschaut, aber leider noch nichts geeignetes gefunden.

Also in meinem Script werden die zulöschenden Bilder mittels Checkboxen makiert (name="loeschen"), und anschließend mittels als Datensatz übergeben. Das ganze schaut dann ungefähr so aus:

loeschen=Feb18_11.JPG&loeschen=IM003003.JPG

nun sollten eigentlich die Bilder, Feb18_11.JPG und IM003003.JPG mittels Dateinamen aus der Datenbank gelöscht werden, leider klappt das aber bisher immer nur wenn ich so splitte, dass nur eine Datei gelöscht wird.

ein kurzer Ausschnitt aus dem Script:

read(STDIN, $daten, $ENV{'CONTENT_LENGTH'});

@all= split ( /&/, $daten);

foreach $new_daten (@all) {

($para, $value) =split (/=/, $new_daten);

$value =~ tr/+/ /;
   $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
   $value =~ s///g;
   $value =~ s/<([^>]|\n)*>//g;
   $FM{$para} = $value;
}

#so wird halt leider immer nur 1 Bild gelöscht

$sth = $dbh->prepare ("DELETE FROM $table1
     WHERE name_pic = ('$FM{'loeschen'}') ");
$sth->execute ;
$sth->finish ;

Hab das ganze auch schon über arrays probiert und über Zeichenketten, leider bisher ergebnisslos :(

Kann mir da vielleicht mal jemand auf die Sprünge helfen?

Besten Dank!

Mfg Jan

  1. Hi,

    Ist es eigentlich möglich mehrere Bilder aus der Datenbank aufeinmal löschen?

    Na klar.

    Hab schon n paar Stunden im Forum und auch sonst überall nachgeschaut, aber leider noch nichts geeignetes gefunden.

    ein kurzer Ausschnitt aus dem Script:

    #so wird halt leider immer nur 1 Bild gelöscht

    $sth = $dbh->prepare ("DELETE FROM $table1
         WHERE name_pic = ('$FM{'loeschen'}') ");

    Aua! Autsch!

    Bitte mach ein Quote vorher:

    $FM{'loeschen'} = $dbh->quote($FM{'loeschen'});
    (Oder so, hab gerade das DBI-Buch nicht zur Hand)

    $sth->execute ;
    $sth->finish ;

    Was spricht denn dagegen, statt nur eine Spezialanfrage mehrere
    Anfragen mit OR zu verknuepfen?

    $query = "DELETE FROM $table1
              WHERE "name_pic" = '$name1'
                OR "name_pic" = '$name2'";

    Eine andere Moeglichkeit waere eine LIKE-Anfrage nach den Namen.

    Aber beschreib lieber mal genauer, welche Bilder du eigentlich loeschen willst?
    Wenn du einfach alle Loeschen willst, geht auch der brutale weg:
    "DROP TABLE $table1"  >:)

    Ciao,
      Wolfgang

  2. Hi,
    ich hab eigentlich keine ahnung von perl aber versuch dein mysql string doch mal mit einer AND kombination.

    grüsse, christian

  3. hi Jan,

    ich glaube, das Proplem ist weniger deine mysql-Anweisung, sondern die Zeichenübergabe an dein CGI-Script. Überleg Dir mal was das mit deinen übergebenen Daten macht.

    Es definiert ein Hash namens %FM und speichert nach obigem Schema deine ganzen übergegbenen Daten in $FM{'fmname'} = fmwert.
    Jetzt benutzt du beim Übergeben der einzelnen Bildernamen jeweils loeschen=bildername, aber beide Male mit 'loeschen' als 'fmname'. Dadurch wird in deinem Hash der erste Eintrag, in deinem Beispiel 'Feb18_11.JPG', durch den zweiten Wert, 'IM003003.JPG', ersetzt. Also kennt dein CGI-Script den ersten garnicht mehr.
    Eine Lösung für dieses Problem wäre, du fragst in der foreach-Schleife nach, ob gerade 'loeschen' übergeben wird und definierst den ein neues eigenes Hash, z.B. %DELETE.

    Meiner Meinung nach am besten so:

    my $i = 0;

    foreach $new_daten (@all) {

    ($para, $value) =split (/=/, $new_daten);

    $value =~ tr/+/ /;
       $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
       $value =~ s///g;
       $value =~ s/<([^>]|\n)*>//g;

    if($para == "loeschen") {
       $DELETE{'$i'} = $value; $i++;
      }
      else {
       $FM{$para} = $value;
      }
    }

    Nun hast du deine ganzen Bildernamen in einem eigenen Hash, von welchem du später die Anzahl der Einträge abfragen und über die Zahlen die einzelnen Einträge auslesen kannst.

    Viel Spass sonst noch beim Perl-Programmieren...

    Sebastian

    1. $DELETE{'$i'} = $value; $i++;

      die zeile heißt besser:

      $DELETE{$i} = $value;$i++;

    2. Hallo,

      my $i = 0;

      [...]

      $DELETE{'$i'} = $value; $i++;

      Nicht immer ist es Sinnvoll mit Hashes zu arbeiten. In Deinem Beispiel wäre ein Array vollkommen ausreichend, ja sogar die bessere Wahl, da damit einiges eleganter gearbeitet werden kann, und außerdem Speicherplatz spart, was sich vor allem bei größeren Datenmengen auswirkt.

      Grüße
       Klaus

  4. Hallo,

    loeschen=Feb18_11.JPG&loeschen=IM003003.JPG

    read(STDIN, $daten, $ENV{'CONTENT_LENGTH'});

    [...]

    $FM{$para} = $value;

    Da Du zwei CGI-Parameter mit dem gleichen Namen verwendest, wird beim jedem Durchlauf $FM{'loeschen'} überschrieben.
    Somit wird halt nur das letzte Bild gelöscht. Du mußt DIr irgend etwas anderes einfallen lassen, wie etwa mit einem Array zu arbeiten.
    Besser wäre es, wenn DU Dich mit dem MOdul CGI.pm beschäftigst, da dieses viel lästige Anpassungsarbeiten überflüssig macht. Der von Dir verwendete Code ist überhaupt nicht robust, sprich, er hat massive Schwierigkeiten, auf allfällige Änderungen bei der Parameterübergabe zu reagierien.

    BTW: es ist nicht gerade perlish, wenn Du Variablenbezeichner GROSS schreibst. Lies dazu 'perldoc perlstyle'.

    #so wird halt leider immer nur 1 Bild gelöscht

    $sth = $dbh->prepare ("DELETE FROM $table1
         WHERE name_pic = ('$FM{'loeschen'}') ");
    $sth->execute ;
    $sth->finish ;

    Entweder Du verwendest das schon angesprochene OR in der WHERE-Klausel oder Bind-Variablen.
    Hier ein Beispiel mit einer Bind-Variable, welches ich für übersichtlicher halte.

    $sth = $dbh->prepare ("DELETE FROM $table1 WHERE name_pic = ?");
    foreach $bild (@zu_loeschende_bilder)
      {
      $sth->execute($bild);
      }
    $sth->finish;

    Näheres findest Du in der DBI-Dokumentation.

    Grüße
      Klaus

  5. Hallo,

    Tach

    Ist es eigentlich möglich mehrere Bilder aus der Datenbank aufeinmal löschen?

    Ja.

    $sth = $dbh->prepare ("DELETE FROM $table1
         WHERE name_pic = ('$FM{'loeschen'}') ");

    WHERE name_pic IN (wert1, wert2, wert3);

    (dürfen natürlich mehr oder weniger als 3 Werte sein.)

    Andreas