|
|
@@ -913,21 +913,73 @@ class utils {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * LIMIT的处理,或者超过10
|
|
|
+ * LIMIT的处理,或者超过100
|
|
|
+ * 如果有limit 给最后一个limit修改
|
|
|
+ * 这个处理不了 写在字段里的子查询(select 1 from aa limit 1) as aa,sql会原样返回
|
|
|
*/
|
|
|
- public static function processLimitClause($sql) {
|
|
|
- // 查找不区分大小写的 LIMIT 位置
|
|
|
- $limitPos = stripos($sql, 'LIMIT');
|
|
|
-
|
|
|
- if ($limitPos !== false) {
|
|
|
- // 截取 LIMIT 之前的部分,拼接固定内容
|
|
|
- $processed = substr($sql, 0, $limitPos) . 'LIMIT 10';
|
|
|
+ public static function processLimitClause($sql,$limit = 100) {
|
|
|
+ $is_limit = false;
|
|
|
+ // 去除前后空白
|
|
|
+ $sql = trim($sql);
|
|
|
+
|
|
|
+ // 临时保存字符串内容,防止被误匹配
|
|
|
+ $placeholder = '__SQL_STRING_PLACEHOLDER__';
|
|
|
+ $strings = [];
|
|
|
+
|
|
|
+ // 匹配字符串(包括单引号和 $$ 符号)
|
|
|
+ $pattern = "/('(?:[^']|'')*')|(\$(?:.*?)\$)/is";
|
|
|
+
|
|
|
+ // 替换所有字符串为占位符,并保存原内容
|
|
|
+ $cleanSql = preg_replace_callback($pattern, function ($match) use (&$strings, $placeholder) {
|
|
|
+ $str = $match[1] ?? $match[2];
|
|
|
+ $index = count($strings);
|
|
|
+ $strings[$index] = $str;
|
|
|
+ return $placeholder . $index;
|
|
|
+ }, $sql);
|
|
|
+
|
|
|
+ // 正则匹配所有 LIMIT 子句(支持 LIMIT n 和 LIMIT n OFFSET m)
|
|
|
+ $pattern = '/\s+LIMIT\s+\d+(\s+OFFSET\s+\d+)?/i';
|
|
|
+
|
|
|
+ preg_match_all($pattern, $cleanSql, $matches, PREG_OFFSET_CAPTURE);
|
|
|
+
|
|
|
+ if (!empty($matches[0])) {
|
|
|
+ // 获取最后一个 LIMIT 的位置和内容
|
|
|
+ $lastMatch = end($matches[0]);
|
|
|
+ $limitStr = $lastMatch[0]; // 完整的 LIMIT 子句,如 " LIMIT 50" 或 " LIMIT 200 OFFSET 10"
|
|
|
+ $pos = $lastMatch[1]; // 起始位置
|
|
|
+
|
|
|
+ // 提取 LIMIT 的数字部分
|
|
|
+ preg_match('/\d+/', $limitStr, $numMatch);
|
|
|
+ $currentLimit = intval($numMatch[0]);
|
|
|
+
|
|
|
+ if ($currentLimit < $limit) {
|
|
|
+ // 当前 LIMIT 值更小,不做修改
|
|
|
+ $is_limit = true;
|
|
|
+ }else{
|
|
|
+ // 构造新的 LIMIT 子句,保留可能存在的 OFFSET
|
|
|
+ $offsetPart = '';
|
|
|
+ if (preg_match('/(.*?)(\s+OFFSET\s+\d+)/i', $limitStr, $offsetMatches)) {
|
|
|
+ $offsetPart = $offsetMatches[2]; // 例如 " OFFSET 10"
|
|
|
+ }
|
|
|
+ $newLimitClause = " LIMIT {$limit}{$offsetPart}";
|
|
|
+
|
|
|
+ // 替换最后一个 LIMIT
|
|
|
+ $before = substr($cleanSql, 0, $pos);
|
|
|
+ $after = substr($cleanSql, $pos + strlen($limitStr));
|
|
|
+
|
|
|
+ $cleanSql = $before . $newLimitClause . $after;
|
|
|
+ }
|
|
|
} else {
|
|
|
- // 无 LIMIT 时直接追加
|
|
|
- $processed = $sql . ' LIMIT 10';
|
|
|
+ // 没有 LIMIT,直接加上
|
|
|
+ $cleanSql .= " LIMIT {$limit}";
|
|
|
}
|
|
|
-
|
|
|
- return $processed;
|
|
|
+
|
|
|
+ // 最后恢复原来的字符串内容
|
|
|
+ $finalSql = preg_replace_callback("/{$placeholder}(\d+)/", function ($match) use ($strings) {
|
|
|
+ return $strings[(int)$match[1]];
|
|
|
+ }, $cleanSql);
|
|
|
+
|
|
|
+ return array("sql"=>$finalSql, "is_limit"=>$is_limit);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -978,7 +1030,7 @@ class utils {
|
|
|
//检查模板 是否已经带有特定表格的序列
|
|
|
if(!empty($explode_str) && strpos($template, $explode_str) !== false){
|
|
|
$spacing = utils::getMarkDownTableSpacing($template,$explode_str);
|
|
|
- $parts = explode("$explode_str", $template,2);
|
|
|
+ $parts = explode($explode_str, $template,2);
|
|
|
|
|
|
// 生成所有行
|
|
|
$generatedRows = [];
|
|
|
@@ -997,6 +1049,7 @@ class utils {
|
|
|
$mapping = $explode_data['mapping'];
|
|
|
if(!$mapping){
|
|
|
$parts[0] = utils::replacements($data[0],$parts[0],$new_sql);
|
|
|
+ $parts[1] = utils::replacements($data[0],$parts[1],$new_sql);
|
|
|
}
|
|
|
|
|
|
$replaceTemplate = $parts[0] . implode($spacing, $generatedRows) . $parts[1];
|