在YII中一次插入多行

时间:2012-01-05 20:34:02

标签: php yii

我已经完成了http://www.yiiframework.com/doc/guide/1.1/en/form.table

我不明白这意味着什么:

$items=$this->getItemsToUpdate();

这个$this->getItemsToUpdate()功能是什么?

我试图一次插入动态行。我使用jquery来创建数据,但我不知道如何将它们插入到数据库中。

4 个答案:

答案 0 :(得分:8)

Yii支持添加多条记录。

使用此....

 $alertStatus[] = array(
                        'db_field_name1' => $value1,
                        'db_field_name1' => $value2, 
                        'created_on' => new CDbExpression('NOW()'),
                        'modified_on' => new CDbExpression('NOW()')
                    );
 $connection = Yii::app()->db->getSchema()->getCommandBuilder();
 $command = $connection->createMultipleInsertCommand('table_name', $alertStatus);
            $command->execute();

$ alertStatus数组应该包含数据库的所有字段

答案 1 :(得分:1)

如果您不限制使用Active Records,则可以使用DAO执行适当的SQL插入语句以插入多行。你可以在这里找到这样一个陈述的例子:

Insert multiple records into MySQL with a single query

一旦将insert语句作为字符串(可以使用循环动态构造,以防您事先不知道需要插入多少行),就可以像这样执行:

$sql = 'INSERT statement goes here';
$connection = Yii::app() -> db;
$command = $connection -> createCommand($sql);
$command -> execute();

答案 2 :(得分:1)

我遇到了同样的问题。

据我所知,Yii没有默认功能来插入多行。

所以我在CdbCommand类中创建了一个(framework / db / CDbCommand.php):

/**
 * Creates and executes an INSERT SQL statement for several rows.
 * @param string $table the table that new rows will be inserted into.
 * @param array $array_columns the array of column datas array(array(name=>value,...),...) to be inserted into the table.
 * @return integer number of rows affected by the execution.
 */
public function insertSeveral($table, $array_columns)
{
    $sql = '';
    $params = array();
    $i = 0;
    foreach ($array_columns as $columns) {
        $names = array();
        $placeholders = array();
        foreach ($columns as $name => $value) {
            if (!$i) {
                $names[] = $this->_connection->quoteColumnName($name);
            }
            if ($value instanceof CDbExpression) {
                $placeholders[] = $value->expression;
                foreach ($value->params as $n => $v)
                    $params[$n] = $v;
            } else {
                $placeholders[] = ':' . $name . $i;
                $params[':' . $name . $i] = $value;
            }
        }
        if (!$i) {
            $sql = 'INSERT INTO ' . $this->_connection->quoteTableName($table)
                . ' (' . implode(', ', $names) . ') VALUES ('
                . implode(', ', $placeholders) . ')';
        } else {
            $sql .= ',(' . implode(', ', $placeholders) . ')';
        }
        $i++;
    }
    return $this->setText($sql)->execute($params);
}

用法:

$rows = array(
            array('id' => 1, 'name' => 'John'),
            array('id' => 2, 'name' => 'Mark')
);
$command = Yii::app()->db->createCommand();
$command->insertSeveral('users', $rows);

<强>更新

正如Nabi K.A.Z.所提到的,最好不要触及框架的源代码。 在我的项目中,我实际创建了类MyCDbCommand(扩展了 CDbCommand )并且我创建了MyCDBConnection(扩展了 CDbConnection )。

MyCDbCommand (扩展CDbCommand):

class MyCDbCommand extends CDbCommand
{
    protected $_connection;

    public function __construct(CDbConnection $connection, $query = null)
    {
        $this->_connection = $connection;
        parent::__construct($connection, $query);
    }

    /**
     * Creates and executes an INSERT SQL statement for several rows.
     * @param string $table the table that new rows will be inserted into.
     * @param array $array_columns the array of column datas array(array(name=>value,...),...) to be inserted into the table.
     * @return integer number of rows affected by the execution.
     */
    public function insertSeveral($table, $array_columns)
    {
        $sql    = '';
        $params = array();
        $i      = 0;
        foreach ($array_columns as $columns) {
            $names        = array();
            $placeholders = array();
            foreach ($columns as $name => $value) {
                if (!$i) {
                    $names[] = $this->_connection->quoteColumnName($name);
                }
                if ($value instanceof CDbExpression) {
                    $placeholders[] = $value->expression;
                    foreach ($value->params as $n => $v) {
                        $params[$n] = $v;
                    }
                } else {
                    $placeholders[]           = ':' . $name . $i;
                    $params[':' . $name . $i] = $value;
                }
            }
            if (!$i) {
                $sql = 'INSERT INTO ' . $this->_connection->quoteTableName($table)
                    . ' (' . implode(', ', $names) . ') VALUES ('
                    . implode(', ', $placeholders) . ')';
            } else {
                $sql .= ',(' . implode(', ', $placeholders) . ')';
            }
            $i++;
        }
        return !empty($sql) ? $this->setText($sql)->execute($params) : 0;
    }

}

MyCDBConnection (扩展CDbConnection并使用MyCDbCommand):

class MyCDbConnection extends CDbConnection
{

    public function createCommand($query = null)
    {
        $this->setActive(true);
        return new MyCDbCommand($this, $query);
    }
}

然后我更改了配置文件(/protected/config/main.php)。 我在那里将CDbConnection更改为MyCDbConnection:

...
'components'=>array(
    ...
    'db' => array(
        'connectionString' => 'mysql:host=localhost;dbname=dname',
        'username'         => 'user',
        'password'         => 'password',
        'charset'          => 'utf8',
        'class'            => 'MyCDbConnection', // Change default CDbConnection class to MyCDbConnection
    ),
    ...
    )
...

你走了。我们在没有触及核心框架的情况下完成了它,您可以像以前一样使用它。

答案 3 :(得分:0)

Pigalev Pavel的上述代码非常棒。

但是需要修改核心框架,这很糟糕!

所以,我写了一个独立的班级。

将此代码放在components文件名下的GeneralRepository.php文件夹中。

<?php
class GeneralRepository
{
    /**
     * Creates and executes an INSERT SQL statement for several rows.
     * 
     * Usage:
     * $rows = array(
     *      array('id' => 1, 'name' => 'John'),
     *      array('id' => 2, 'name' => 'Mark')
     * );
     * GeneralRepository::insertSeveral(User::model()->tableName(), $rows);
     * 
     * @param string $table the table that new rows will be inserted into.
     * @param array $array_columns the array of column datas array(array(name=>value,...),...) to be inserted into the table.
     * @return integer number of rows affected by the execution.
     */
    public static function insertSeveral($table, $array_columns)
    {
        $connection = Yii::app()->db;
        $sql = '';
        $params = array();
        $i = 0;
        foreach ($array_columns as $columns) {
            $names = array();
            $placeholders = array();
            foreach ($columns as $name => $value) {
                if (!$i) {
                    $names[] = $connection->quoteColumnName($name);
                }
                if ($value instanceof CDbExpression) {
                    $placeholders[] = $value->expression;
                    foreach ($value->params as $n => $v)
                        $params[$n] = $v;
                } else {
                    $placeholders[] = ':' . $name . $i;
                    $params[':' . $name . $i] = $value;
                }
            }
            if (!$i) {
                $sql = 'INSERT INTO ' . $connection->quoteTableName($table)
                . ' (' . implode(', ', $names) . ') VALUES ('
                . implode(', ', $placeholders) . ')';
            } else {
                $sql .= ',(' . implode(', ', $placeholders) . ')';
            }
            $i++;
        }
        $command = Yii::app()->db->createCommand($sql);
        return $command->execute($params);
    }
}

在任何地方使用:

$rows = array(
    array('id' => 1, 'name' => 'John'),
    array('id' => 2, 'name' => 'Mark')
);
GeneralRepository::insertSeveral(User::model()->tableName(), $rows);