php - 用于正确分割嵌套 SQL 分隔符的正则表达式

标签 php mysql regex preg-replace

我正在处理一个包含多个 SQL 查询的字符串:

ALTER TABLE _version ADD test1 INT NOT NULL;
ALTER TABLE _version ADD test2 INT NOT NULL;
CREATE PROCEDURE test3 ()
        LANGUAGE SQL
        DETERMINISTIC
        SQL SECURITY DEFINER
        COMMENT 'A procedure'
        BEGIN
            SELECT 'Hello World !';
        END;

我希望将此字符串拆分为三个单独查询的数组,如下所示:

ALTER TABLE _version ADD test1 INT NOT NULL;

ALTER TABLE _version ADD test5 INT NOT NULL;

CREATE PROCEDURE test3 ()
        LANGUAGE SQL
        DETERMINISTIC
        SQL SECURITY DEFINER
        COMMENT 'A procedure'
        BEGIN
            SELECT 'Hello World !';
        END;

这将允许我使用 PDO 进行多个查询。因为不幸的是(据我所知)您无法使用 PDO 从一条语句进行多个事务查询。也就是说,您不能在 PDO 查询中使用 DELIMITER $$ SQL 命令。

但是,请注意 BEGINEND 之间的 ; 分隔符。这导致了问题!如果我只是使用 ; 分隔符分解字符串,它就无法正确分离出过程。

我一直在摆弄正则表达式来查找 BEGINEND 之间不存在的所有内容,然后用其他内容替换这些分隔符(例如 $$ 分隔符)——然后对 $$ 分隔符进行爆炸——但似乎没有任何效果。

这是我迄今为止在 PHP 和正则表达式中尝试过的(糟糕的)尝试,其中 $sqlString 是包含多个查询的字符串:

$sqlString = preg_replace("#(?<!BEGIN.+);(?!.+END)#",'$$',$sqlString);
$splitQueries = explode("$$",$sqlString);

但是我无法让负面的前瞻/后顾工作发挥作用。请帮助我找出正确的正则表达式模式或正确的方向!

最佳答案

免责声明:这只是按照您的要求进行操作,并在 ; 之后分割输入,除非在 BEGIN/ 之间>END 语句(它会在诸如 WHERE column = ';'.

之类的情况下失败

此 PHP 语句将完全按照您的需要执行 ( RegEx demo ):

$splitQueries = preg_split('/(?<=;)(?!(?:(?!BEGIN).)*END)/s', $sqlString);
array_pop($splitQueries); // there is an extra value in the array, assuming
                          // your query ends in ; 

首先,我对分号使用了正向后查找,这样您就可以只使用一个简单的 preg_split()调用(因为它实际上不会匹配 ;,而是匹配它后面的空格)。

接下来,我接着进行否定前瞻:(?!.*END)。这是需要 s 修饰符的地方,因为它使 . 匹配换行符。

最后,我将否定前瞻中的 .* 替换为另一个否定前瞻:(?:(?!BEGIN).)*.

我们的最终结果会查找分号(从技术上讲,是分号后面的空格),然后查看后面的每个字符(除非我们看到 BEGIN),以确保没有 END (表明我们处于 BEGIN/END 语句内)。有趣!

关于php - 用于正确分割嵌套 SQL 分隔符的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32149059/

相关文章:

php - 将用户数据存储在服务器上的 JSON 文件中

php - 从模型实例 YII 获取模型名称

php - PHP-MYSQL SELECT 查询时间长

mysql - 如何从自定义mysql数据库自动导入wordpress内容?

python - 如何使用 * 或捕获字符串?用 python 正则表达式中的组

PHP 电子邮件表单 - 定义发件人

Mysql事件执行开始时间

php - 如何在 Sublime Text Build 中获取文件夹名称

ios - 从 NSString 中提取数字的最快且最高效的方法是什么?

mysql - 从表中复制字段以在另一个表的查询中使用