2016-07-26 23 views
2

我的情況是這樣的:當是這樣哪一個更好?何時或如果其他?

情況:

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; 
} 

如果別人是這樣的:

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; 
} 

我已經嘗試過了。上述所有類型的工作。但在這裏我問,哪一個更好?

+2

你爲什麼把基於你的MySQL代碼中一個PHP變量的條件?找出想要執行的查詢,然後運行正確的查詢。不要將其轉儲到數據庫中。 – tadman

+2

另外,請,**不要**內聯任意值。儘可能使用[帶有佔位符值的預處理語句](http://stackoverflow.com/questions/10968527/escaping-sql-queries-in-codeigniter)。 – tadman

+0

這是他的代碼功能,我猜...只是比較哪個查詢會更好用。一個組合lols –

回答

2

這不可能是正確的,第一個代碼不應該工作!在SQL中,CASE是一個表達式,而不是一個語句。你不能在THEN部分放一個條件,只有一個值。 MySQL將布爾表達式評估爲1 \ 0,因此您的情況基本如下:

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

大多數RDBMS都會引發錯誤。

您可以格式化它是這樣的:只要你沒有性能問題

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 = ?  

,也不想想這事, 它只會浪費你的時間。選擇一個容易維護的軟件。

+0

非常感謝。我已經嘗試了上述兩種方法,並且工作。我使用mysql數據庫 –

+0

你如何看待第二種方式(如果有)?如果它很好用? –

+0

是的,沒關係,就像@ dburmann說的那樣,它可以導致SQL注入,但總的來說,選擇一個更容易維護。他們都很好,但有時在網站方面做計算和邏輯是首選。 – sagi

2

除了@sagi提出的問題,實際上第二種方法更好一些有點不相關的理由。在第一個示例中,您直接在查詢字符串內部使用變量$action,該變量可能會爲SQL注入打開一個攻擊向量,因爲它來自方法範圍之外,可能不安全。而在第二個例子中,變量$condition在該方法中被控制並且使用安全。

除此之外,只要性能不成問題,我會選擇可讀性。出於這個原因,我甚至可以把它分成3個單獨的,明確命名的函數,而它們有一個非常相似的SQL。這樣總是清楚發生了什麼事情,每個案例可以獨立「增長」,而不是1個方法,其中添加了越來越多的案例和ifs。

編輯:你也可以清楚地說明它的功能,例如:

  • getAllTransactionCounts()
  • getTransactionCountForCustomers($ transactionIds)
  • getTransactionCountForCustomer($客戶ID)
+0

所以你認爲第二種方式(如果沒有)是沒有問題的? –

+0

@samueltoh我沒有看到第二種方法的主要問題,但仍然需要一些重構。例如,當customer_id和action都爲空時會發生什麼?如果group_id作爲數組提供,而不是以逗號分隔的列表提供?這就是爲什麼我建議用3種方法(可能是由'get_opportunity'調用的私有方法)分割它,只有必要的參數才能使這些案例更清晰和更易於管理。 – dbrumann

+0

非常感謝 –