【问题标题】:Extract values inside parenthesis from MySQL INSERT query string从 MySQL INSERT 查询字符串中提取括号内的值
【发布时间】:2019-06-26 22:48:17
【问题描述】:

我们已经收到了数千个这样的 MySQL INSERT 查询字符串:

$sql = INSERT INTO my_table VALUES ( 123, '456', 'Don't fail', 'hellow world' )

sql 字符串只是在一个项目中提供给我们的。

问题是,在某些查询中,某些字段值在中间有单引号,因此在运行mysqli_query($sql) 时会引发错误。

在我的例子中,如果我转义整个 $sql 字符串,它也会转义 \'456\' 或 \'Don\'t fail\',这也会抛出错误,这就是我需要分别提取和转义值,然后将 sql 查询重新组合在一起。

我需要从括号内提取值并将它们放入一个数组中,这样我就可以单独对它们进行转义。 像这样的:

$vals[0] = 123
$vals[0] = 456
$vals[0] = Don't fail
$vals[0] = hellow world

有没有我可以使用的正则表达式?

我知道“my_table”表的列数。

还有其他解决方案吗?

谢谢

【问题讨论】:

  • 你为什么要逃避他们?它们是如何产生的?这是在 SQL 文件中吗? cakePHP 与此有什么关系?还是 MySQLi?
  • sql字符串只是在一个项目中给我们的。在我的例子中,如果我转义整个 $sql 字符串,它也会转义 \'456\' 或 \'Don\'t fail\',这也会抛出和错误,这就是我需要提取和转义的原因单独的值,然后将 sql 查询重新组合在一起。
  • 不,我的意思是你从哪里得到这种格式的 SQL?我想这不是精灵给你的。如果它来自 mysqldump 或 phpMyAdmin,它已经被转义了。如果它是由某人手动编写的,那么问题是为什么?
  • @Alex mysqli_real_escape_string 对完整的 SQL 查询有何帮助?
  • @Dharman 我们有一个巨大的 sql 转储文件,其中包含 750 多个表和数百万行,当我将它导入 phpmyadmin 时,它会超时。因此,我设法在原始大转储上使用 file_get_contents 将其划分为 750 个较小的 .sql 转储(每个表一个)。也许这就是他们没有逃脱的原因?如何改用 IDE?

标签: php mysql regex mysqli


【解决方案1】:

您可以创建一个匹配整个 SQL 字符串并捕获每个值的模式,而不是尝试转义撇号。

$pattern = "/(?:[ \w]+ \() (\d+), '(\d+)', '(.+?)', '(.+?)' \)/";

然后将这些值作为参数绑定到每个插入语句的预准备语句。

$stmt = $mysqli->prepare('INSERT INTO my_table VALUES (?, ?, ?, ?)');

foreach ($inserts as $insert) {
    preg_match($pattern, $insert, $matches);
    list ($full, $a, $b, $c, $d) = $matches;
    $stmt->bindValue("isss", $a, $b, $c, $d);
    $stmt->execute();
}

【讨论】:

  • 如果其他表的其他 INSERT 查询具有不同的模式和列数,即 ('123', 'abce', 123, 'what's up', 1, 'nice' ) 怎么办。有没有办法让模式更通用?
  • 哦,我还以为是同一个插入。是的,可能是这样,但我现在不在电脑旁。等我回来再看看
【解决方案2】:

你要非常小心,不要在这里得到意想不到的结果,

<?php

$re = '/\b\'\b/';  // b for word boudry

$str = <<<EOT
$sql = INSERT INTO my_table VALUES ( 123, '456', 'Don't fail', 'hellow world' )
EOT;

$subst = '\\\\\'';

$result = preg_replace($re, $subst, $str);

echo $result;

如果以双撇号开头或结尾将不起作用,即:$sql = INSERT INTO my_table VALUES ( 123, '456', 'Don't fail', 'hellow worlds'' )

演示:https://regex101.com/r/Ast9A7/1

【讨论】:

  • 有很多情况下撇号位于单词的末尾,因此正则表达式失败(不会被转义)。
  • @tim 这太棒了!!它正在处理所有字符串的 99.9999%。但是,它并没有逃脱这一点:VALUES (13318,'In 'Campus Confidential,' a Professor Laments That Teaching Is Not the Priority of Teachers','https://www.nytimes.com/','1510604711.html',1510604491) 为什么?
  • @tim 它没有转义这个字符串值:In 'Campus Confidential,' a Professor Laments That Teaching Is Not the Priority of Teachers
  • 告诉你它不会是完美的,你需要根据你的具体需求进行调整
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 2016-12-24
  • 1970-01-01
  • 2010-11-01
  • 2016-08-19
  • 2019-07-29
  • 2019-05-14
相关资源
最近更新 更多