Обновление Zend Framework из другой таблицы - PullRequest
1 голос
/ 23 июля 2011

У меня есть модель в Zend Framework, которая распространяется на Zend_Db_Table, где $this->_name = 'tableA'.

Очень приятно, как долго я делаю insert(), update() или delete().Как я могу реализовать обновление основной таблицы на основе значения из другой таблицы ..?

В необработанном запросе SQL это может выглядеть так:

UPDATE tableA SET fieldA = tableB.newValue
FROM tableB
WHERE tableA.someValue = tableB.someIndex // it will be complicate manipulation
  AND tableA.index = .....

как я могу построить параметры для update()Метод:

parent::update( $data, $where );

Ответы [ 2 ]

1 голос
/ 23 июля 2011

Нет возможных комбинаций того, как создать параметры для метода parent::update(), чтобы получить окончательный запрос на обновление.Причина в том, что метод Db Table update просто передает переменные $data и $where в метод update адаптера Db.Метод адаптера update не оставляет места для добавления дополнительной информации. Вы не можете взломать параметры вообще

Если вы не можете использовать связи таблиц с каскадным обновлением.Лучше всего будет расширить адаптер Db и создать новый метод для обработки этих типов обновлений.Это должно сработать.

/** 
 * Add this method to you custom adapter
 * Direct copy of update method with integration of $from
 * @see Zend_Db_Adapter_Abstract::update
 **/
public function updateFrom($table, $from, array $bind, $where = '')
{
    /**
     * Build "col = ?" pairs for the statement,
     * except for Zend_Db_Expr which is treated literally.
     */
    $set = array();
    $i = 0;
    foreach ($bind as $col => $val) {
        if ($val instanceof Zend_Db_Expr) {
            $val = $val->__toString();
            unset($bind[$col]);
        } else {
            if ($this->supportsParameters('positional')) {
                $val = '?';
            } else {
                if ($this->supportsParameters('named')) {
                    unset($bind[$col]);
                    $bind[':col'.$i] = $val;
                    $val = ':col'.$i;
                    $i++;
                } else {
                    /** @see Zend_Db_Adapter_Exception */
                    require_once 'Zend/Db/Adapter/Exception.php';
                    throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");
                }
            }
        }
        // Reason #1 you can't hack into $data array to pass reference to a table
        $set[] = $this->quoteIdentifier($col, true) . ' = ' . $val;
    }

    $where = $this->_whereExpr($where);

    /**
     * Build the UPDATE statement
     */
    $sql = "UPDATE "
         . $this->quoteIdentifier($table, true)
         . ' SET ' . implode(', ', $set)
         . ' FROM ' . $this->quoteIdentifier($from, true) // My only edit
         . (($where) ? " WHERE $where" : ''); // Reason #2 no room in where clause

    /**
     * Execute the statement and return the number of affected rows
     */
    if ($this->supportsParameters('positional')) {
        $stmt = $this->query($sql, array_values($bind));
    } else {
        $stmt = $this->query($sql, $bind);
    }
    $result = $stmt->rowCount();
    return $result;
}

/** Add this to your extended Zend_Db_Table **/
public function update(array $data, $where)
{
    $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
    $from      = 'schema.name'; // Get from table name 
    return $this->_db->updateFrom($tableSpec, $from, $data, $where);
}

Примечание. Я не проверял это, но уверен, что все будет работать так, как ожидалось.Если у вас есть какие-либо проблемы, просто дайте мне знать.Поскольку я скопировал метод обновления адаптера, я пошел дальше и добавил примечания о причинах, по которым вы не можете взломать эти параметры.

РЕДАКТИРОВАТЬ Я почти забыл упомянуть.Каждый адаптер уникален, поэтому вам нужно будет проверить метод обновления адаптеров.Я только что скопировал с Zend_Db_Abstract.

0 голосов
/ 23 июля 2011
...