Zend Framework:数据库查找抛出“主键列太少”异常

时间:2012-07-10 20:14:52

标签: zend-framework

我正在尝试使用find函数按ID查询数据库表。该表有4个主键(3个外键) 这是表数据网关的代码:

class Application_Model_DbTable_Assigneduser extends Zend_Db_Table_Abstract
{  
    protected $_name = 'assigneduser';  
}  

这是Mapper的代码:

public function find($id)
{
    $result = $this->getDbTable()->find($id);
    if(count($result) == 0)
        return;
    $row=$result->current();
    $assignedUser = new Application_Model_AssignedUser();
    $assignedUser->setId($row->id)
        ->setIdProject($row->id_project)
        ->setIdUser($row->id_user)
            ->setIdTask($row->id_task);
}  

我用来实例化mapper的代码以及我使用方法find的位置:

public function indexAction()
{
        echo "<xmp>";
        $user=new Application_Model_AssignedUserMapper();
        print_r($user->find(3));
        echo '</xmp>';
}  

我使用print_rxmp标记来详细了解代码返回的内容。我收到的异常消息是:

Message: Too few columns for the primary key  

我不知道如何解决它。任何的想法?谢谢!

2 个答案:

答案 0 :(得分:1)

好的find()将按主键返回行,如果需要传递复合主键,则只返回主键,它必须是数组。

以下是find()的文档块:

/**
 * Fetches rows by primary key.  The argument specifies one or more primary
 * key value(s).  To find multiple rows by primary key, the argument must
 * be an array.
 *
 * This method accepts a variable number of arguments.  If the table has a
 * multi-column primary key, the number of arguments must be the same as
 * the number of columns in the primary key.  To find multiple rows in a
 * table with a multi-column primary key, each argument must be an array
 * with the same number of elements.
 *
 * The find() method always returns a Rowset object, even if only one row
 * was found.
 *
 * @param  mixed $key The value(s) of the primary keys.
 * @return Zend_Db_Table_Rowset_Abstract Row(s) matching the criteria.
 * @throws Zend_Db_Table_Exception
 */

修复:

class Application_Model_DbTable_Assigneduser extends Zend_Db_Table_Abstract
{  
    protected $_name = 'assigneduser';
    protected $_primary = array('column','column'...); //This is not strictly required but may help.
} 


public function indexAction()
{
        $user=new Application_Model_AssignedUserMapper();
        Zend_Debug::dump($user->find(array(3,,,)), 'User');//outputs formatted var_dump with optional label as second arg.
} 

现在让这个变得简单:

public function find($id)
{
    $select = $this->getDbTable->select();
    $select->where('id = ?', $id);
    $result = $this->getDbTable()->fetchRow($select);//will return only one row, if you need more use fetchAll()
    if(is_null($result)) //fetchRow() returns NULL if no rows found.
        return;
    $row=$result;
    $assignedUser = new Application_Model_AssignedUser();
    $assignedUser->setId($row->id)
                 ->setIdProject($row->id_project)
                 ->setIdUser($row->id_user)
                  ->setIdTask($row->id_task);
}  

使用fetchRow()可以查询行中的任何列,但只返回一行。如果您需要返回行集,则可以使用具有相同查询选项的fetchAll(),您将获得行集。

希望这有帮助。

答案 1 :(得分:0)

我遇到了同样的问题。在ZF版本1.11.11上,就像RockyFord所说的那样,你只需要在DbTable类中映射一个像这样的主键的列数组:

class AssignedUser extends Zend_Db_Table_Abstract
{
    protected $_name = 'assigned_user';
    protected $_primary = array('user_id','project_id','task_id');
}

但是当你想要找到这条记录时,你不能只找到一个主键,甚至不能用它们传递一个数组(这就是我正在做的事情),find方法正在等待无限数量的参数作为主键的值(遵循您声明的相同顺序),如下所示:

$assignedUserTable = new AssignedUser();
$rowset = $assignedUserTable->find( $userId, $projectId, $taskId );
$row = $rowset->current();