微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 如何使用Zend_Db_Adapter每次调用“查询”运行多个SQL查询?

这是我编写的Zend_Application_Resource,用于在部署中进行更改时自动更新架构.

<?PHP

/**
 * Makes sure the current schema version matches what we're expecting for this
 * particular version of the application.
 * 
 * The version of the database is compared against the value configured in
 * application.ini. sql scripts corresponding to versions between the database
 * version's and the current local sql scripts are run against the database to
 * get things up to date.
 *
 * @copyright 2011 Case Western Reserve University,College of Arts and Sciences
 * @author Billy O'Neal III (bro4@case.edu)
 */
class Cas_Application_Resource_Schema extends Zend_Application_Resource_ResourceAbstract
{
    /**
     * Creates an array of filepaths corresponding to the scripts that need
     * to run.
     * 
     * @param int $from
     * @param int $to
     * @return array
     */
    private function GetScriptsToRun($from,$to)
    {
        $application = APPLICATION_PATH . '/configs/sql/';
        $result = array();
        for($cur = $from + 1; $cur <= $to; $cur++)
        {
            $result[] = "{$application}{$cur}.sql";
        }
        return $result;
    }

    /**
     * Returns the version the application is locally configured to expect.
     * 
     * @return int
     */
    private function GetLocalVersion()
    {
        $options = $this->getoptions();
        $version = (int)$options['version'];
        return $version;
    }

    /**
     * Returns the version the database thinks it is.
     * 
     * @return int
     */
    private function GetDbVersion()
    {
        $adapter = Zend_Db_Table::getDefaultAdapter();
        $MetadataTable = new Cas_Model_Table_Metadata;
        $verQuery = $MetadataTable->select()->from($MetadataTable,array('Value'));
        $verQuery->where("{$adapter->quoteIdentifier('Key')} = ?",'Version');
        $dbVersion = $adapter->fetchOne($verQuery);
        return (int)$dbVersion;
    }

    /**
     * Runs the specified filepath's file contents as a sql script.
     * 
     * @param string $scriptPath
     */
    private function RunsqlScript($scriptPath)
    {
        $adapter = Zend_Db_Table::getDefaultAdapter();
        $contents = file_get_contents($scriptPath);
        $adapter->query($contents);
    }

    /**
     * Updates the version number in the database to match the version
     * specified in the local configuration file.
     */
    private function UpdateVersion()
    {
        $MetadataTable = new Cas_Model_Table_Metadata;
        $MetadataTable->delete(array("{$MetadataTable->getAdapter()->quoteIdentifier('Key')} = ?" => 'Version'));
        $MetadataTable->insert(array('Version' => $this->GetLocalVersion()));
    }

    /**
     * Performs the actual schema checks.
     */
    public function init()
    {
        //We depend on the database being connected.
        $this->getBootstrap()->bootstrap('db');
        $local = $this->GetLocalVersion();
        $remote = $this->GetDbVersion();
        if ($local < $remote)
        {
            throw new Exception('Database version is newer than local version.');
        }
        else if ($remote < $local)
        {
            $scripts = self::GetScriptsToRun($remote,$local);
            foreach($scripts as $script)
            {
                $this->RunsqlScript($script);
            }
            $this->UpdateVersion();
        }
    }
}

这失败是因为有问题的脚本(例如configs / sql / 1.sql,configs / sql / 2.sql等)包含多个sql语句,用; s分隔,并带有如下消息:

Zend_Db_Statement_MysqLi_Exception: MysqLi prepare error: You have an error in your sql Syntax; check the manual that corresponds to your MysqL server version for the right Syntax to use near ‘;’

解决方法

Zend_Db_Adapter不支持 multi_query().

您可以选择解决方法

>调用$adapter-> getConnection(),它将返回底层MysqLi资源的实例.您可以调用此资源的multi_query()方法.
>将文件内容拆分为单个sql语句的数组,并为每个语句调用$adapter-> query(). Be careful about edge cases.
>使用shell_exec()调用MySQL命令行工具的子进程来处理sql脚本.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐