繁体   English   中英

使用Doctrine DBAL创建视图和存储过程

[英]Using Doctrine DBAL to create views and stored procedures

我们在Symfony2应用程序中使用Doctrine。 为了帮助进行一些数据库交互,我们定义了一些视图和存储过程。 它们存储在我们项目源的特定目录中,然后置于版本控制下,这样团队中的每个人都可以访问它们。 每个视图或存储过程都有其自己的.sql文件,其中包含将创建视图/存储过程的查询,其中包括“如果已存在则删除”行。

我们编写了一个控制台命令来遍历包含.sql文件的目录,然后通过从Doctrine dbal连接创建的PDO对象向数据库发出查询。

对MySQL查询日志的检查显示,每个“ CREATE VIEW”和“ CREATE PROCEDURE”命令均已执行,并且PDO连接没有出现任何错误。 但是,当我们在命令运行后检查数据库时,并不是所有预期的项目都存在。 这有点奇怪...目前,我们有创建3个视图和1个存储过程的命令。 当我们第一次运行命令时,将创建其中两个视图。 然后,我们再次运行它,并创建第三个视图。 无论运行命令多少次,都不会创建存储过程。

因此,任何人都可以就为什么会发生这种情况提供任何帮助。 数据库用户具有必要的特权,查询日志表明一切正常。

这是console命令的execute方法;

/**
* execute command
*
* @param InputInterface  $input
* @param OutputInterface $output
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
    $path = $input->getArgument('path');

    $this->setAbsolutePath($path);

    if (!$this->doesPathExist()) {
        throw new \InvalidArgumentException($this->absolutePath.' does not exist, or is not a directory');
    }

    $files = $this->getFiles();

    foreach ($files as $file) {
        $bits = explode('.', $file);
        if (count($bits)>1) {
            $extension = end($bits);
            if (strtolower($extension) === 'sql' ) {

                if ($this->runScript($file)) {
                    $output->writeln($file.' ran successfully!');
                } else {
                    $output->writeln($file. ' errored!');
                }
            }
        }
    }

    $output->writeln('Done');
}

将该方法称为“ runScript” ...

/**
* run script
* executes the sql commands in the provided file
* returns true if the script executed, false otherwise
*
* @param string $filename
*
* @return boolean
*/
private function runScript($filename)
{
    $em = $this->getContainer()->get('doctrine')->getManager();

    $connection = $em->getConnection();
    $host = $connection->getHost();
    $username = $connection->getUsername();
    $password = $connection->getPassword();
    $database = $connection->getDatabase();
    $pdoConn = new \PDO('mysql:host=' . $host . ';dbname=' . $database, $username, $password);

    $result = false;

    if ($pdoConn) {
        $result = false;
        $script = file_get_contents($this->absolutePath.'/'.$filename);
        $stmt = $pdoConn->prepare($script);
        try {
            $result = $stmt->execute();
        } catch (\PDOException $e) {
            $result = false;
        }
        unset($stmt);
    }
    unset($pdoConn);

    return $result;
}

如您所见,我们一直在尝试创建一个全新的PDO数据库连接以发出命令。 运行该命令时,它将列出四个.sql文件,并说它们都已成功运行。

如果我们在命令行上使用MySQL在MySQL上执行.sql文件目录,并使用Symfony用于连接数据库的同一用户,则所有视图和过程均正确创建,因此我们确定.sql中没有错误。文件。

我们很沮丧!

问题是在存储过程的定义中使用了DELIMITER $$。 该定义最初是使用MySQL命令行编写的,因此需要区分表示命令结尾的实分号和存储过程中的分号,因此对定界符进行了更改。

通过DBAL / PDO连接创建存储过程时不需要此操作。

因此,简而言之,解决方案是在创建存储过程的整个.sql脚本中坚持使用分号作为分隔符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM