zend 框架从另一个表更新

发布于 2024-11-25 11:45:22 字数 532 浏览 1 评论 0原文

我在 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 );

I got model in Zend Framework what extends Zend_Db_Table where $this->_name = 'tableA'.

It is very nice how long I doing insert(), update(), or delete(). How I can realize updating main table based on value from another table.. ?

In raw SQL query it could looks like this:

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

how I can build params for update() method:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Saygoodbye 2024-12-02 11:45:22

没有可能的组合来构建 parent::update() 方法的参数来获取最终的更新查询。原因是因为 Db Table update 方法只是将您的 $data$where 变量传递给 Db Adapter 的 update方法。适配器的 update 方法没有留下附加附加信息的空间。 您根本无法破解参数

如果您无法使用级联更新的表关系,那么 。最好的选择是扩展数据库适配器并创建一个新方法来处理这些类型的更新。这应该有效。

/** 
 * 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 复制。

There are no possible combinations of how to build params for the parent::update() method to get that final update query. The reason is because the Db Table update method just passes along your $data and $where variables to the Db Adapter's update method. The adapter's update method leaves no room for attaching additional information. You can't hack params at all

If you can't use table relationships with cascade update. Your best bet will be to extend the Db Adapter and create a new method to handle these types of updates. This should work.

/** 
 * 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);
}

Note: I didn't test this out, but I am pretty confident it will work as expected. If you have any problems, just let me know. Because I copied the adapter's update method, I went ahead and added notes of the reasons why you can't hack those params.

EDIT
I almost forgot to mention. Every adapter is unique so you will have to check with your adapters update method. I just copied from Zend_Db_Abstract.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文