2015-04-21 106 views
3

我遵循的CakePHP 3的食譜來創建一個case語句 http://book.cakephp.org/3.0/en/orm/query-builder.html#case-statementsCakePHP的3.0 - 爲case語句查詢生成器

,但並不如預期的結果SQL查詢。該聲明的「否則」部分缺失

這是我的代碼:

$query = $this->Attendees->find()->contain(['Users']); 
$lastModifedCase = $query->newExpr()->addCase($query->newExpr()->add(['Attendees.modified <' => 'Users.modified']), [ 'Users.modified', 'Attendees.modified'], 'datetime'); 
$query->select(['Attendees.id', 'lastModified' => $lastModifedCase, 'Users.firstName', 'Users.lastName']); 

die(var_dump($query->__debugInfo())); 

在debuginfo軟,這是我能看到的SQL:

array(13) { 
    ["sql"]=> 
    string(265) "SELECT Attendees.id AS `Attendees__id`, (CASE WHEN Attendees.modified < :c0 THEN :c1 END) AS `lastModified`, Users.firstName AS `Users__firstName`, Users.lastName AS `Users__lastName` FROM attendees Attendees INNER JOIN users Users ON Users.id = (Attendees.user_id)" 
    ["params"]=> 
    array(2) { 
    [":c0"]=> 
    array(3) { 
     ["value"]=> 
     string(14) "Users.modified" 
     ["type"]=> 
     string(8) "datetime" 
     ["placeholder"]=> 
     string(2) "c0" 
    } 
    [":c1"]=> 
    array(3) { 
     ["value"]=> 
     string(14) "Users.modified" 
     ["type"]=> 
     string(8) "datetime" 
     ["placeholder"]=> 
     string(2) "c1" 
    } 
    } 
    ["defaultTypes"]=> 
    array(8) { 
    ["Attendees.id"]=> 
    string(7) "integer" 
    ["id"]=> 
    string(7) "integer" 
    ["Attendees.user_id"]=> 
    string(7) "integer" 
    ["user_id"]=> 
    string(7) "integer" 
    ["Attendees.created"]=> 
    string(8) "datetime" 
    ["created"]=> 
    string(8) "datetime" 
    ["Attendees.modified"]=> 
    string(8) "datetime" 
    ["modified"]=> 
    string(8) "datetime" 
    } 

的「搞笑」事情是,食譜中的例子包含一個錯誤(變量$ unpublishedCase應該是$ notPublishedCase),也不會給我預期的結果。這是其debuginfo軟(PS:我只能通過我的與會者表測試的例子改爲「$這個 - >文章」)

array(13) { 
    ["sql"]=> 
    string(190) "SELECT (SUM(CASE WHEN published = :c0 THEN :c1 END)) AS `number_published`, (SUM(CASE WHEN published = :c2 THEN :c3 END)) AS `number_unpublished` FROM attendees Attendees GROUP BY published " 
    ["params"]=> 
    array(4) { 
    [":c0"]=> 
    array(3) { 
     ["value"]=> 
     string(1) "Y" 
     ["type"]=> 
     NULL 
     ["placeholder"]=> 
     string(2) "c0" 
    } 
    [":c1"]=> 
    array(3) { 
     ["value"]=> 
     int(1) 
     ["type"]=> 
     string(7) "integer" 
     ["placeholder"]=> 
     string(2) "c1" 
    } 
    [":c2"]=> 
    array(3) { 
     ["value"]=> 
     string(1) "N" 
     ["type"]=> 
     NULL 
     ["placeholder"]=> 
     string(2) "c2" 
    } 
    [":c3"]=> 
    array(3) { 
     ["value"]=> 
     int(1) 
     ["type"]=> 
     string(7) "integer" 
     ["placeholder"]=> 
     string(2) "c3" 
    } 
    } 
    ["defaultTypes"]=> 
    array(8) { 
    ["Attendees.id"]=> 
    string(7) "integer" 
    ["id"]=> 
    string(7) "integer" 
    ["Attendees.user_id"]=> 
    string(7) "integer" 
    ["user_id"]=> 
    string(7) "integer" 
    ["Attendees.created"]=> 
    string(8) "datetime" 
    ["created"]=> 
    string(8) "datetime" 
    ["Attendees.modified"]=> 
    string(8) "datetime" 
    ["modified"]=> 
    string(8) "datetime" 
    } 

當我深入到CakePHP的代碼,我想我的問題來自的構造Cake \ Database \ Expression \ CaseExpression:

public function __construct($conditions = [], $values = [], $types = []) 
    { 

     if (!empty($conditions)) { 
      $this->add($conditions, $values, $types); 
     } 

     if (is_array($conditions) && is_array($values) && count($values) > count($conditions)) { 
      end($values); 
      $key = key($values); 
      $this->elseValue($values[$key], isset($types[$key]) ? $types[$key] : null); 
     } 
    } 

$條件不被視爲一個數組,因此else值沒有設置。

的CakePHP的版本是3.0.1

的PHP版本是5.4.34

你們覺得呢?我做錯了什麼或者它是一個錯誤?

預先感謝您的啓示

回答

1

我發現我錯一個美好的夜晚之後,我跟大家分享吧...希望這會幫助別人一天。

語法不正確,所以$ condition絕對不是數組。

$lastModifedCase = $query->newExpr()->addCase(
    $query->newExpr()->add([ 
     'Attendees.modified <' => 'Users.modified' 
    ]), 
    ['Users.modified', 'Attendees.modified'], 
    'datetime' 
); 

正確的語法是:

$lastModifedCase = $query->newExpr()->addCase(
    [$query->newExpr()->add('Attendees.modified < Users.modified')], 
    [ 'Users.modified', 'Attendees.modified'], 
    ['datetime','datetime'] 
); 

我還:基於何洛倫佐的答案

  • 調整的條件
  • 中指定的類型的每一個值(一數組'datetime'而不是單個字符串的 )。否則,我得到了一個「錯誤類型」的錯誤。
1

當你使用,你需要記住的是,陣列的價值相提並論總是被視爲PARAM而不是原始字符串生成條件的數組語法:

['field_name >' => 'this is just a value, not a raw string'] 

原因是它可以防止SQL注入攻擊。解決您的問題這樣做:

['Attendees.modified < Users.modified'] 

取而代之的是:

['Attendees.modified <' => 'Users.modified'] 
+0

感謝您的意見。我調整了我的代碼。事實上,這消除了不必要的參數。不幸的是,這並不能解決我關於sql語句中缺少'ELSE'的問題。 – DavidC