【问题标题】:Zend Predicate or PredicatsetZend 谓词或谓词集
【发布时间】:2016-02-03 09:11:25
【问题描述】:

我想在我的请求中添加括号,但我不知道怎么做。你能帮助我吗 ? 我的 SQL 查询:

SELECT * 
FROM vw_my_asn_header 
WHERE username = 'toto' 
  AND (shipment_number LIKE '20151106052811' OR 
       shipment_number LIKE '20151110053250' OR 
       shipment_number LIKE '20151116054359') 
ORDER BY message_id ASC

我的功能:

public function searchSitesDeliveries($username, Search $search)
{
     $select = $this->tableGateway->getSql()->select();
     array(new Predicate\Expression('username = ?', $username)),Predicate\PredicateSet::COMBINED_BY_AND);

    if (!empty($search->get_shipment_number()))
    {
      $valeur = $search->get_shipment_number();
      if(is_array($valeur)) 
      {
          $valeur = array_unique($valeur);
          foreach ($valeur as $key => $value) 
          {
              if($key == 0)
              {
                $predicate_set->andPredicate(new Predicate\Expression('shipment_number IN', '%'.$value.'%'));
                $predicate_set->nest();
                $bool = true;
              }
              else
              {
                  $predicate_set->orPredicate(new Predicate\Like('shipment_number', '%'.$value.'%'));     
              }
           }
           if($bool == true)   
           {
               $predicate_set->unnest();                             
           }
        }
        else {
           $predicate_set->andPredicate(new Predicate\Like('shipment_number', '%'.$valeur.'%'));
        }
    }

    $select->where($predicate_set);
    $resultSet = $this->tableGateway->selectWith($select);

    return $resultSet;
}

$predicate_set->nest;给我带来下一个错误:

`Call to undefined method Zend\Db\Sql\Predicate\PredicateSet::nest()`

在文件的开头,我:

命名空间 Front\Model;

use Zend\Paginator\Adapter\DbSelect;
use Zend\Paginator\Paginator;

use Zend\Db;
use Zend\Db\Sql;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Expression;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Metadata\Metadata;
use Zend\Db\Sql\Predicate;
use Zend\Db\Sql\Predicate\PredicateSet;
use Zend\Db\ResultSet\ResultSet;

使用 Front\Model\MAH;

有什么问题?

谢谢

我写了一个测试:

public function searchSitesDeliveries($username, Search $search)
{
        if (!empty($search->get_shipment_number()))
        {
            $valeur = $search->get_shipment_number();
            if(is_array($valeur))
            {
                $toto = array();
                $valeur = array_unique($valeur);
                $select = $this->tableGateway->getSql()->select(); 
                $titi = "$" ;
                $compteur = 0;
                foreach ($valeur as $key => $value) 
                {                    
                    $toto[$compteur] = $value;
                    $compteur = $compteur + 1;
                }
                for ($i=0; $i < ($compteur); $i++) { 
                    \Zend\Debug\Debug::dump($toto[$i]);
                    if($i== 0 || $i == $compteur )
                    {
                        $titi = $titi . "select->where->equalTo('user_name', '".$username."')->next->like('shipment_number','".$toto[$i]."')";    
                    }
                    else
                    {                     
                        $titi = $titi . "->or->like('shipment_number','".$toto[$i]."')->unnest;";
                    }
                }   
                \Zend\Debug\Debug::dump($titi);             
                $resultSet = $this->tableGateway->selectWith(eval($titi));
            }
        }
        return $resultSet;
}

但是:

string(173) "$select->where->equalTo('user_name', 'toto')->next->like('shipment_number','20151125056269')->or->like('shipment_number','20151014048501')->unnest;"

和:

Message error : Not nested

【问题讨论】:

  • 您的代码中可能有错误,因为 $predicate_set 未定义。但是如果你看一下 zend-db 的类,Predicate 类扩展了 PredicateSet 并定义了方法 nest() 和 unnest()。
  • 您可以按照 newage 的说明进行修复。就个人而言,我没有使用 PredicateSet 类,而是使用 Predicate 类(或 Where,它是相同的)。
  • 你有一个带有谓词类的例子。
  • 我的问题是动态的,解决方案是动态的。由于我有一个数据表,所以我不知道其内容的大小。

标签: zend-framework zend-framework2 zend-db


【解决方案1】:

这个例子更简单

$select->where->equalTo('user_name', $userName)
   ->nest()
       ->like('shipment_number', '20151106052811')
       ->or
       ->like('shipment_number', '20151110053250')
       ->or
       ->like('shipment_number', '20151116054359')
   ->unnest()

如果你想使用Predicate's

$predicate = new Predicate\PredicateSet(
    [
        new Predicate\Operator('user_name', Predicate\Operator::OPERATOR_EQUAL_TO, $userName),
        new Predicate\PredicateSet(
            [
                new Predicate\Like('shipment_number', '20151106052811'),
                new Predicate\Like('shipment_number', '20151110053250'),
                new Predicate\Like('shipment_number', '20151116054359'),
            ],
            Predicate\Predicate::COMBINED_BY_OR
    ],
    Predicate\Predicate::COMBINED_BY_AND
);
$select->where->addPredicate($predicate);

【讨论】:

    【解决方案2】:

    这是一个动态解决方案:

    use Zend\Db\Sql\Where;
    
    public function searchSitesDeliveries($username, Search $search)
    {
        if (!empty($search->get_shipment_number()))
        {
            $valeur = $search->get_shipment_number();
            if(is_array($valeur))
            {
                $result = array();
                $valeur = array_unique($valeur);
                $where = new Where();
                $where->equalTo('username', $username);
                if (!empty($valeur) {
                      $where->nest();
                      $or = false;
                    foreach ($valeur as $value) 
                    {   
                          if ($or) $where->or;
                        $where->like('shipment_number', $value)
                        $or = true;
                    }
                    $where->unnest();
                }
                $select = $this->tableGateway->getSql()->select();             
                $select->where($where);
                $resultSet = $this->tableGateway->selectWith($select);
                return $resultSet;
            }
            // error processing ... when $valeur isn't an array
        }
        // error processing ... when get_shipment_number is empty
    }
    

    【讨论】:

      【解决方案3】:

      我认为@newage 的响应是好的,但也许你可以像这样使用 IN SQL 语句

      SELECT * 
      FROM vw_my_asn_header 
      WHERE username = 'toto'
        AND shipment_number IN ('20151106052811', '20151110053250', '20151116054359')      
      ORDER BY message_id ASC
      

      你可以使用 Zend\Db

      new Predicate\In('shipment_number',array('20151106052811', '20151110053250', '20151116054359'))
      

      【讨论】:

        【解决方案4】:

        我正在做这个解决方案,它可以工作,但我不喜欢我的代码,因为它是静态的,如果有人有技巧让它成为动态的,我很感兴趣。

        public function searchSitesDeliveries($username, Search $search)
        {
            if (!empty($search->get_shipment_number()))
            {
                $valeur = $search->get_shipment_number();
                if(is_array($valeur))
                {
                    $result = array();
                    $valeur = array_unique($valeur);
                    $compteur = 0;
                    foreach ($valeur as $key => $value) 
                    {   
                        $compteur = $compteur + 1;                             
                        $result[$compteur] = $value;
                    }
                    $select = $this->tableGateway->getSql()->select(); 
                    switch($compteur)
                    {
                        case '1':
                            $predicate_set = new Predicate\PredicateSet(array(new Predicate\Expression('username = ?', $username)), Predicate\PredicateSet::COMBINED_BY_AND);
                            $predicate_set->andPredicate(new Predicate\Like('shipment_number', '%'.$valeur.'%')); 
                            $select->where($predicate_set);
                        break;
                        case '2':
                            $select->where->equalTo('username', $username)
                           ->nest()
                               ->like('shipment_number', ''.$result[1].'')
                               ->or
                               ->like('shipment_number', ''.$result[2].'')
                           ->unnest();
                        break;
                        case '3':
                            $select->where->equalTo('username', $username)
                            ->nest()
                               ->like('shipment_number', ''.$result[1].'')
                               ->or
                               ->like('shipment_number', ''.$result[2].'')
                                  ->or
                               ->like('shipment_number', ''.$result[3].'')
                           ->unnest();
                        break;
                        case '4':
                            $select->where->equalTo('username', $username)
                            ->nest()
                               ->like('shipment_number', ''.$result[1].'')
                               ->or
                               ->like('shipment_number', ''.$result[2].'')
                               ->or
                               ->like('shipment_number', ''.$result[3].'')
                               ->or
                               ->like('shipment_number', ''.$result[4].'')
                           ->unnest();
                        break;
                        case '5':
                            $select->where->equalTo('username', $username)
                            ->nest()
                               ->like('shipment_number', ''.$result[1].'')
                               ->or
                               ->like('shipment_number', ''.$result[2].'')
                               ->or
                               ->like('shipment_number', ''.$result[3].'')
                               ->or
                               ->like('shipment_number', ''.$result[4].'')
                                ->or
                               ->like('shipment_number', ''.$result[5].'')
                           ->unnest();
                        break;
                        case '6':
                         $select->where->equalTo('username', $username)
                            ->nest()
                               ->like('shipment_number', ''.$result[1].'')
                               ->or
                               ->like('shipment_number', ''.$result[2].'')
                               ->or
                               ->like('shipment_number', ''.$result[3].'')
                               ->or
                               ->like('shipment_number', ''.$result[4].'')
                                ->or
                               ->like('shipment_number', ''.$result[5].'')
                               ->or
                               ->like('shipment_number', ''.$result[6].'')
                           ->unnest();
                        break;
                        case '7':
                            $select->where->equalTo('username', $username)
                            ->nest()
                                ->like('shipment_number', ''.$result[1].'')
                                ->or
                                ->like('shipment_number', ''.$result[2].'')
                                ->or
                                ->like('shipment_number', ''.$result[3].'')
                                ->or
                                ->like('shipment_number', ''.$result[4].'')
                                ->or
                                ->like('shipment_number', ''.$result[5].'')
                                ->or
                                ->like('shipment_number', ''.$result[6].'')
                                ->or
                                ->like('shipment_number', ''.$result[7].'')
                           ->unnest();
                        break;
                        case '8':
                            $select->where->equalTo('username', $username)
                            ->nest()
                                ->like('shipment_number', ''.$result[1].'')
                                ->or
                                ->like('shipment_number', ''.$result[2].'')
                                ->or
                                ->like('shipment_number', ''.$result[3].'')
                                ->or
                                ->like('shipment_number', ''.$result[4].'')
                                ->or
                                ->like('shipment_number', ''.$result[5].'')
                                ->or
                                ->like('shipment_number', ''.$result[6].'')
                                ->or
                                ->like('shipment_number', ''.$result[7].'')                            
                                ->or
                                ->like('shipment_number', ''.$result[8].'')
                           ->unnest();
                        break;
                        case '9':
                            $select->where->equalTo('username', $username)
                            ->nest()
                                ->like('shipment_number', ''.$result[1].'')
                                ->or
                                ->like('shipment_number', ''.$result[2].'')
                                ->or
                                ->like('shipment_number', ''.$result[3].'')
                                ->or
                                ->like('shipment_number', ''.$result[4].'')
                                ->or
                                ->like('shipment_number', ''.$result[5].'')
                                ->or
                                ->like('shipment_number', ''.$result[6].'')
                                ->or
                                ->like('shipment_number', ''.$result[7].'')                            
                                ->or
                                ->like('shipment_number', ''.$result[8].'')
                                ->or
                                ->like('shipment_number', ''.$result[9].'')
                           ->unnest();
                        break;
                    }
                    $resultSet = $this->tableGateway->selectWith($select);
                }
        
            }
            return $resultSet;  
        }
        

        【讨论】:

          【解决方案5】:
          if(is_array($valeur)) {
              $nest = false;
              $valeur = array_unique($valeur);
          
              /* Select */
              $select = $this->tableGateway->getSql()->select();
              $where = $select->where('user_name', $userName);
          
              /* Open nest if $valuer has more 1 values */
              if ($nest === false && count($valuer) > 1) {
                  $nest = true;
                  $where = $where->nest();
              }
          
              /* Add like and or to where */
              while (count($valuer) > 0) {
                  $value = array_shift($valuer);
                  $where = $where->like('shipment_number', $value);
                  if (count($valuer) > 0) {
                      $where = $where->or;
                  }
              }
          
              /* Close nest */
              if ($nest === true && empty($valuer)) {
                  $where->unnest();
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-01-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多