You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用多分隔符解析SQL语句的SELECT与ORDERBY部分?

解决C++多分隔符解析SQL的简便方法

核心思路

不用逐个处理分隔符,直接借助C++标准库的stringstream结合自定义字符分类规则,一次性识别空格、冒号、逗号作为分隔符,高效提取SELECT和ORDERBY部分的目标字段。

具体实现步骤

  1. 截取目标子串:先从完整SQL中单独提取SELECT ... FROM和ORDERBY ...;这两段核心内容,避免无关语句干扰解析。
  2. 自定义分隔符规则:通过重载ctype facet,将空格、冒号、逗号标记为分隔符,让stringstream自动按这些字符拆分字符串。
  3. 提取有效字段:遍历拆分后的token,当遇到值为1的标记时,将其前一个token(字段名)加入结果列表。

完整代码示例

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <locale>

// 自定义分隔符的字符分类规则
struct MultiDelimiter : std::ctype<char> {
    MultiDelimiter() : std::ctype<char>(get_table()) {}
    static const mask* get_table() {
        static std::vector<mask> rc(table_size, mask());
        rc[' '] = std::ctype_base::space;
        rc[':'] = std::ctype_base::space;
        rc[','] = std::ctype_base::space;
        return &rc[0];
    }
};

// 解析字段的通用函数
std::vector<std::string> parse_fields(const std::string& input) {
    std::vector<std::string> fields;
    std::stringstream ss(input);
    // 注入自定义分隔符规则
    ss.imbue(std::locale(ss.getloc(), new MultiDelimiter));
    
    std::string token;
    std::string prev_token;
    while (ss >> token) {
        if (token == "1" && !prev_token.empty()) {
            fields.push_back(prev_token);
            prev_token.clear();
        } else {
            prev_token = token;
        }
    }
    return fields;
}

int main() {
    std::string sql = "SELECT LNAME:1,FNAME:1,SALARY:1 FROM EMPLOYEE WHERE SALARY >= 30000 ORDERBY SALARY:1;";
    
    // 提取SELECT部分
    size_t select_start = sql.find("SELECT") + 6;
    size_t select_end = sql.find("FROM");
    std::string select_part = sql.substr(select_start, select_end - select_start);
    auto select_fields = parse_fields(select_part);
    
    std::cout << "解析SELECT字段:" << std::endl;
    for (const auto& f : select_fields) {
        std::cout << "- " << f << std::endl;
    }
    
    // 提取ORDERBY部分
    size_t orderby_start = sql.find("ORDERBY") + 7;
    size_t orderby_end = sql.find(";");
    std::string orderby_part = sql.substr(orderby_start, orderby_end - orderby_start);
    auto orderby_fields = parse_fields(orderby_part);
    
    std::cout << "\n解析ORDERBY字段:" << std::endl;
    for (const auto& f : orderby_fields) {
        std::cout << "- " << f << std::endl;
    }
    
    return 0;
}

代码说明

  • 自定义MultiDelimiter:将空格、冒号、逗号统一标记为空格类字符,stringstream读取时会自动跳过这些分隔符,直接返回连续的字段名或标记值。
  • 字段提取逻辑:通过记录前一个token,匹配字段名:1的格式,精准提取需要的字段名称。
  • 子串截取:先分离出需要解析的目标段落,避免WHERE等其他语句的内容干扰解析流程。

运行结果

解析SELECT字段:
- LNAME
- FNAME
- SALARY

解析ORDERBY字段:
- SALARY

内容的提问来源于stack exchange,提问作者anirudh raghavan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:46:13