hawkmaster: Unterschiede bei PDO::ERRMODE_EXCEPTION an oder aus, UNIQUE

Hallo zusammen,
ich versuche mal testweise einen Insert in eine MySQL Tabelle mit PDO.
(Es wurden noch keine Daten validiert bzw. maskiert)

$d_name = $_POST['depname'];
$result = $DBO->query("SELECT dep_name FROM departments") or warning($DBO);
while ($row = $result->fetch()){
 if (strtoupper($d_name) != strtoupper($row['dep_name'])){
 $DBO->exec("INSERT INTO infostream_departments (dep_name) VALUES ('$d_name')");
...

Wenn nun;
$DBO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
aktiviert erscheint die unten stehende Fehlermeldung wenn es einen Eintrag schon gibt.

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'Marketing' for key 2' in

Die Spalte "dep_name" ist auf "UNIQUE! gesetzt damit es keine doppelten Einträge gibt.

wenn ich die Option;
$DBO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
deaktiviere klappt alles, es gibt KEINE doppelten Einträge und es kommt keine Fehlermeldung.

Mit mysql_query() gab es auch keine Fehlermeldungen.

Mit ist klar das ich eine Prüfung auf doppelte Einträge anders abfangen muss.
Eigentlich kann man es ja schon mit "UNIQUE" verhindern.
Was ist die saubere Lösung?
PDO::ERRMODE_EXCEPTION immer aktivieren und mögliche Fehler vorher abfangen?

vielen Dank und viele Grüße
hawk

  1. Das Arbeiten mit Ausnahmen erleichtert die Arbeit teilweise schon sehr. Ich würde deshalb bei PDO::ERRMODE_EXCEPTION bleiben.
    Wenn du etwa den von dir genannten Fehler abfangen willst, verwende einfach einen Try-Catch-Block:

      
    <?php  
    [...]  
    try {  
        //Deine Queries  
    } catch(PDOException $e) {  
        if($e->getCode() == 23000) {  
            //Duplicate entry  
        }  
    }  
    [...]  
    ?>  
    
    

    Mit set_exception_handler() kannst du eine globale Methode festlegen, die die Ausnahmen auffängt, die nicht durch ein catch gefangen werden.

    Noch etwas: Wenn du schon PDO verwendest, kannst du auch gleich Prepared Statements verwenden. Schau dir dazu die Klasse PDOStatement, die Methode PDO::prepare(), etc. [1] an. Da sparst du dir dann auch Funktionen wie mysql_real_escape_string() bzw. PDO::quote().

    [1] http://at2.php.net/manual/de/ref.pdo.php

    1. Hallo Patrick,
      vielen Dank für deine Hilfe.

      Noch etwas: Wenn du schon PDO verwendest, kannst du auch gleich Prepared Statements verwenden. Schau dir dazu die Klasse PDOStatement, die Methode PDO::prepare(), etc. [1] an. Da sparst du dir dann auch Funktionen wie mysql_real_escape_string() bzw. PDO::quote().

      ich bin noch ganz am Anfang mit PDO und verusche gerade einige Dinge wie ich meinen bisherigen Code umstellen kann.
      Daher fallen mir halt einige Dinge auf, wie z.b. auch das fehlende "mysql_num_rows".
      Das mit den Prepared Statements habe ich mir schon durchgelesen und möchte es demnächst mal ausprobieren.

      Danke nochmals
      Gruss
      hawk

      1. Daher fallen mir halt einige Dinge auf, wie z.b. auch das fehlende "mysql_num_rows".

        Verwende dafür am besten die SQL-Aggregatfunktion COUNT()

        z.B.:

          
        SELECT  
            COUNT(*) AS Num_Rows  
        FROM  
            Foobar;  
        
        

        mysql_affected_rows() ersetzt du einfach durch PDOStatement::rowCount().