如何从查询中删除超过“LIMIT”的所有内容?(详情在里面)


How can I remove everything past "LIMIT" from a query? (details inside)

我得到了一些由我的脚本动态构建的查询。它们通常适合以下模板:

SELECT ... 
FROM ... 
JOIN ... 
WHERE ... (lots of filters, search conditions, etc. here) ... 
ORDER BY (optional) ... 
LIMIT (optional) ... OFFSET (optional)

我想从查询中删除限制和偏移部分。我用了

$sql_entitati = implode("LIMIT", explode("LIMIT", $sql_entitati, -1));

这样做,但后来它击中了我:如果查询中没有 LIMIT 怎么办,如果唯一的 LIMIT 在 where 子句中的某个地方怎么办?

所以我要问你的问题是:如果没有 LIMIT 和/或 where 子句中的某个地方有"限制",我如何安全地删除 LIMIT 关键字之后的所有内容而不会搞砸它?所有这些都是在 php 中完成的。

为清楚起见,进行了一些编辑:

我使用的算法:

$sql = implode("LIMIT", explode("LIMIT", $sql, -1));

将适用于 99% 的案例。当末尾缺少"LIMIT"关键字,并且在条件中的某处写有"LIMIT"时,就会出现问题。例如:

 SELECT * FROM table WHERE bla = 'SPEED LIMIT' ORDER BY table.a

这是我需要解决的问题。

使用以下算法解决(归功于techfoobar):

    $p = strrpos($sql, "LIMIT");
    if($p !== false) {
        $q = strpos($sql, ")", $p);
        $r = strpos($sql, "'", $p);
        $s = strpos($sql, "'"", $p);
        if($q === false && $r === false && $s === false)
            $sql = substr($sql, 0, $p);
    }

你应该做这样的事情:

  1. 获取最后一个"LIMIT"的位置 - 将此位置存储在p
  2. 确保在p之后没有")"字符 - 如果是这样,它是条件等内部查询的一部分。
  3. 确保p后没有"'"字符 - 如果是,则它是某些用户输入字符串的一部分
  4. 如果步骤 2 和 3 已通过,请在p后剥离所有内容

更多提示:

  • 对于步骤 1 - 使用 strrpos 表示最后一次出现LIMIT
  • 对于步骤 2 和 3,请使用带有 pstrpos 作为搜索开始偏移量
  • 对于步骤 4,使用 substr 剥离p后的所有内容

获取 LIMIT 的位置,使用 !==FALSE 然后子字符串检查它是否存在。

$str = "SELECT X FROM Y JOIN WHERE CONDITIONS ORDER BY ORDERS LIMIT OFFSET";
$pos = strrpos($str,"LIMIT");
if ($pos!==false)
{
$newStr = substr($str,0,$pos);
echo $newStr;
}

试试这个 aproach

$query = '';
$query .= 'SELECT...';
$query .= 'FROM ...';
$query .= 'JOIN ...';
$query .= 'WHERE...';
if ($limit)
{
    $query .= " LIMIT $limit";
}

这可能会帮助你...

$str = " SELECT * FROM table WHERE bla = 'SPEED LIMIT' ORDER BY table.a";
$pos = strrpos($str,"LIMIT");
if ($pos!==false)
{
    $ok = 1;
    if(substr_count($str, '"', $pos) % 2 != 0)
    {
        $ok = 0;
    }
    if(substr_count($str, "'", $pos) % 2 != 0)
    {
        $ok = 0;
    }
    if(substr_count($str, ")", $pos) > 0)
    {
        $ok = 0;
    }

    if($ok == 1)
    $str = substr($str,0,$pos);
}
echo $str;