2016-07-26 4 views
2

Mein Fall ist wie folgt aus:Welcher ist besser? Fall wenn oder wenn sonst?

Fall, wenn so:

public function get_opportunity($customer_id, $group_id, $action) 
{ 
    $sql = "SELECT COUNT(transaction_id) AS total_transaction 
      FROM `transaction` 
      WHERE 
       CASE 
        WHEN '$action' = 'view_all' THEN transaction_id IS NOT NULL 
        WHEN '$action' = 'view_group' THEN group_id IN($group_id) 
        ELSE transaction_created_by = ? 
       END 
      "; 

    $result = $this->db->query($sql, array($customer_id))->result_array(); 

    return ($result[0]['total_transaction']) ? $result[0]['total_transaction'] : 0; 
} 

wenn sonst ist wie folgt:

public function get_opportunity($customer_id, $group_id, $action) 
{ 
    if($action == "view_all") 
     $condition = " transaction_id IS NOT NULL"; 
    else if($action == 'view_group') 
     $condition = " group_id IN($group_id)"; 
    else 
     $condition = " customer_id = ?"; 

    $sql = "SELECT COUNT(transaction_id) AS total_transaction 
      FROM `transaction` 
      WHERE $condition"; 

    $result = $this->db->query($sql, array($customer_id))->result_array(); 

    return ($result[0]['total_transaction']) ? $result[0]['total_transaction'] : 0; 
} 

ich versucht habe es. Die ganze Art der obigen Arbeit. Aber hier frage ich, welcher ist besser?

+2

Warum Sie eine Bedingung auf einer PHP-Variablen in Ihrem MySQL-Code basiert setzen? Finden Sie heraus, welche Abfrage Sie ausführen möchten, und führen Sie dann die richtige aus. Speichern Sie das nicht in Ihrer Datenbank. – tadman

+2

Auch, bitte, ** NICHT ** Inline willkürliche Werte. Verwenden Sie wann immer möglich [vorbereitete Anweisungen mit Platzhalterwerten] (http://stackoverflow.com/questions/10968527/escaping-sql-queries-in-codeigniter). – tadman

+0

Dies ist eine Funktion seines Codes, ich denke, vergleichen Sie einfach, welche Abfrage wäre besser zu verwenden. eine Kombination lols –

Antwort

2

Das kann nicht stimmen, der erste Code sollte nicht funktionieren! In SQL CASE ist ein Ausdruck, keine Anweisung. Sie können keine Bedingung auf den THEN Teil setzen, nur einen einzelnen Wert. MySQL wertet Booleschen Ausdrücken als 1 \ 0, so dass Ihr Fall ist im Grunde wie folgt:

WHERE CASE... THEN (Cond) -- equals to 1/0 
       THEN (Cond) -- equals to 1/0 
       ELSE (Cond) -- -- equals to 1/0 

Die meisten RDBMS wird einen Fehler werfen.

Sie können es wie folgt formatiert:

SELECT COUNT(transaction_id) AS total_transaction 
      FROM `transaction` 
      WHERE ('$action' = 'view_all' AND transaction_id IS NOT NULL) OR 
        ('$action' = 'view_group' THEN group_id IN($group_id)) OR 
        transaction_created_by = ?  

Solange man über diese Dinge nicht Performance-Probleme haben, denken Sie nicht, es wird nur Sie Zeit verschwenden. Wählen Sie dasjenige aus, das für Sie leichter zu pflegen ist.

+0

zu verwenden, Vielen Dank. Ich habe beides versucht und es hat funktioniert. Ich benutze MySQL-Datenbank –

+0

Wie denkst du, der zweite Weg (wenn sonst)? Wenn es gut ist zu benutzen? –

+0

Ja, es ist in Ordnung, wie @dburmann sagte, es kann zu SQL-Injection führen, aber im Allgemeinen wählen Sie die eine leichter zu pflegen. Sie sind beide gut, aber manchmal wird Berechnung und Logik auf der Seite der Seite bevorzugt. – sagi

2

Abgesehen von dem von @sagi aufgeworfenen Problem ist der zweite Ansatz aus einem etwas anderen Grund besser. Im ersten Beispiel verwenden Sie die Variable $action direkt in der Abfragezeichenfolge, die möglicherweise einen Angriffsvektor für eine SQL-Injektion öffnet, da sie außerhalb des Methodenbereichs liegt und möglicherweise nicht sicher ist. Während im zweiten Beispiel die Variable $condition in der Methode kontrolliert und sicher zu verwenden ist.

Abgesehen davon würde ich mit Lesbarkeit gehen, solange die Leistung kein Problem ist. Aus diesem Grund könnte ich dies sogar in 3 separate, klar benannte Funktionen aufteilen, die eine sehr ähnliche SQL haben. Auf diese Weise ist immer klar, was passiert und jeder Fall kann unabhängig von einer Methode "wachsen", wo immer mehr Fälle und Wenns hinzugefügt werden.

edit: Auch können Sie die Funktion eindeutig für das, was es tut, z.

  • getAllTransactionCounts()
  • getTransactionCountForCustomers ($ transactionIds)
  • getTransactionCountForCustomer ($ customerId)
+0

also denkst du, dass der zweite Weg (wenn sonst) kein Problem ist? –

+0

@samueltoh Ich sehe keine großen Probleme mit dem zweiten Ansatz, aber einige Refactoring ist noch erforderlich. Was passiert zum Beispiel, wenn customer_id und action null sind? Was passiert, wenn group_id als Array und nicht als kommagetrennte Liste bereitgestellt wird? Aus diesem Grund habe ich vorgeschlagen, es in 3 Methoden aufzuteilen (vielleicht private Methoden, die von 'get_opportunity' aufgerufen werden), mit nur den notwendigen Argumenten, um diese Fälle klarer und einfacher zu verwalten. – dbrumann

+0

Vielen Dank –