使用php解析sql文件

Posted

技术标签:

【中文标题】使用php解析sql文件【英文标题】:Parse sql file using php 【发布时间】:2013-04-11 19:27:19 【问题描述】:

我有一个超过 3gb 的 sql 转储文件,其中包含多个查询。我想使用 php 将文件解析为查询。

根据网站用户的推荐,我使用https://code.google.com/p/php-sql-parser/ 进行解析。问题是使用此方法只能检索第一个查询。

有人有什么建议吗?

转储文件是来自服务器的数据的唯一遗物。

谢谢!

【问题讨论】:

查找引号和转义,搜索; 为什么要解析它?为什么不把它恢复到服务器中呢? 一些查询中有错误。我希望丢弃有缺陷的。而且我的互联网连接有限,所以这次想彻底扫除 一个有错误的 sql 转储?? @KarolyHorvath 我认为文件中的分隔符发生了变化。所以无法搜索; 【参考方案1】:

这是“Principe Orazio”类的改进版本(@AgelessEssence 提到过)。

class sql_parser

    public static function parse($content) 
        $sql_list = [];
        $query = "";
        $lines = explode("\n", $content);
        foreach ($lines as $sql_line)
            $sql_line = trim($sql_line);
            if(($sql_line === "") || (strpos($sql_line, "--") === 0) || (strpos($sql_line, "#") === 0))
                continue;
            

            $query .= $sql_line;
            // Checking whether the line is a valid statement
            if (preg_match("/(.*);$/", $sql_line)) 
                $query = trim($query);
                $query = substr($query, 0, strlen($query) - 1);

                $sql_list[] = sql_parser::remove_query_comments($query);
                //reset the variable
                $query = "";
            
        

        return $sql_list;
    

    public static function remove_query_comments($query)
    
         $sql_comments = '@
              (([\'"]).*?[^\\\]\2) # $1 : Skip single & double quoted expressions
              |(                   # $3 : Match comments
                  (?:\#|--).*?$    # - Single line comments
                  |                # - Multi line (nested) comments
                   /\*             #   . comment open marker
                      (?: [^/*]    #   . non comment-marker characters
                          |/(?!\*) #   . ! not a comment open
                          |\*(?!/) #   . ! not a comment close
                          |(?R)    #   . recursive case
                      )*           #   . repeat eventually
                  \*\/             #   . comment close marker
              )\s*                 # Trim after comments
              |(?<=;)\s+           # Trim after semi-colon
              @msx';


        $query = trim( preg_replace( $sql_comments, '$1', $query ) );

        // Remove the last ;
        if(strrpos($query, ";") === strlen($query) - 1) 
            $query = substr($query, 0, strlen($query) - 1);
        

        return $query;
    

使用它:

$sql_lists = sql_parser::parse(file_get_contents("test.sql"));
print_r($sql_lists);

【讨论】:

【参考方案2】:

我真的找到了你想要的:

SQL Parser: Parse SQL files and extract query statements (( 通过 phpclasses.org ))

示例 sql 文件

#这是一条评论 :) select * from table1 where a=1; --select 评论 2 选择 * 从 表2 其中a=2; #插入值 将忽略插入`versions`(`release`,`revision`,`name`,`lastupdate`)值('1','0','sqlparser',now()); #创建表 创建表`测试`( `id` int(11) unsigned not null auto_increment, `name` varchar(80) not null default '', 主键(`id`) ) 引擎=innodb 默认字符集=utf8; #海关操作 插入`tests`(`id`,`name`) 值('1','test ; value'); update `test` set `name`='test value update' where `id`='1';

输出:

大批 ( 0 => 'SELECT * FROM table1 WHERE a=1', 1 => 'SELECT * FROM table2 where a=2', 2 => 'INSERT IGNORE INTO `VERSIONS`(`release`,`revision`,`name`,`lastUpdate`) 值 (\'1\',\'0\',\'SqlParser\',NOW() )', 3 => 'CREATE TABLE `TESTS` (`Id` int(11) unsigned NOT NULL AUTO_INCREMENT, `Name` varchar(80) NOT NULL DEFAULT \'\', PRIMARY KEY (`Id`)) ENGINE=InnoDB 默认字符集=utf8', 4 => 'INSERT INTO `TESTS`(`Id`,`Name`) VALUES (\'1\',\'test ; value\')', 5 => 'UPDATE `TEST` SET `Name`=\'测试值更新\' WHERE `Id`=\'1\'', )

这个类真正美妙的一点是它可以计算很多东西,比如 cmets、多行和他的值包括“;”的查询字符。

【讨论】:

【参考方案3】:

http://pastebin.com/GxBahnyM - 我从 Typo3 CMS 得到它。 Typo3安装扩展时使用

【讨论】:

【参考方案4】:

是否可以使用 "explode(";", $dumpfile) 拆分转储文件,然后执行循环调用该函数进行解析?您也可以使用其他分隔符进行分解。是否有可能报价不平衡?

问候

芦苇

【讨论】:

是的,看起来是最好的选择。 当查询像:插入表(fieldA,fieldB)值('aa;aa','bb');存在它会破坏文件的正确解析 为此,您可以解析块,如果有不平衡的引用,只需将下一个块添加到前一部分。 如何删除 cmets 或以 -- 开头的行

以上是关于使用php解析sql文件的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis3源码解析-执行SQL流程

使用 PHP 获取 SQL 数据,然后将数组发送到 Javascript

使用 php 和 pdo 执行 .sql 文件

如何使用 php 在 mysql 数据库中导入 .sql 文件

使用SQL将XML文件解析为特定列

使用SQL Server中的OPENXML解析带有内联架构的XML文件