2015-04-21 61 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