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

如何在SQL Server中使用sys.dm_fts_parser解析包含双引号短语的搜索字符串?

如何在SQL Server中使用sys.dm_fts_parser解析包含双引号短语的搜索字符串?

嘿,这个需求确实有点绕——毕竟sys.dm_fts_parser默认会把所有空格分隔的词拆分开,哪怕是引号包裹的短语。不过别担心,我们可以通过自定义解析逻辑来实现你想要的效果,下面给你一个可行的方案:

核心思路

先把原字符串拆分成「单个词」和「引号包裹的短语」两类单元,再对每个单元单独调用sys.dm_fts_parser处理,最后合并结果,这样就能让引号里的短语作为一个整体出现在结果中。

步骤1:创建自定义字符串拆分函数

首先写一个用户定义函数(UDF),用来识别原字符串中的引号短语和普通单词:

CREATE FUNCTION dbo.ParseQuotedString(@input NVARCHAR(MAX))
RETURNS @result TABLE (Term NVARCHAR(MAX))
AS
BEGIN
    DECLARE @start INT = 1, @quoteStart INT, @quoteEnd INT, @currentPos INT;

    WHILE @start <= LEN(@input)
    BEGIN
        -- 定位第一个双引号的位置
        SET @quoteStart = CHARINDEX('"', @input, @start);
        IF @quoteStart = 0
        BEGIN
            -- 没有引号了,拆分剩余内容为单个单词
            DECLARE @remaining NVARCHAR(MAX) = LTRIM(RTRIM(SUBSTRING(@input, @start, LEN(@input)-@start+1)));
            IF @remaining <> ''
            BEGIN
                INSERT INTO @result
                SELECT value FROM STRING_SPLIT(@remaining, ' ') WHERE value <> '';
            END
            BREAK;
        END
        -- 处理引号前的普通内容,拆分为单个单词
        DECLARE @preQuote NVARCHAR(MAX) = LTRIM(RTRIM(SUBSTRING(@input, @start, @quoteStart - @start)));
        IF @preQuote <> ''
        BEGIN
            INSERT INTO @result
            SELECT value FROM STRING_SPLIT(@preQuote, ' ') WHERE value <> '';
        END
        -- 定位匹配的结束引号
        SET @quoteEnd = CHARINDEX('"', @input, @quoteStart + 1);
        IF @quoteEnd = 0
        BEGIN
            -- 未找到闭合引号,把剩余内容作为普通词处理
            INSERT INTO @result VALUES(LTRIM(RTRIM(SUBSTRING(@input, @quoteStart + 1, LEN(@input)-@quoteStart))));
            BREAK;
        END
        -- 提取引号内的完整短语
        INSERT INTO @result VALUES(LTRIM(RTRIM(SUBSTRING(@input, @quoteStart + 1, @quoteEnd - @quoteStart - 1))));
        -- 更新起始位置到结束引号之后
        SET @start = @quoteEnd + 1;
    END
    RETURN;
END

步骤2:调用函数并结合sys.dm_fts_parser处理

用这个拆分函数获取所有单元,再逐个调用sys.dm_fts_parser,最后整理成你要的格式:

DECLARE @input NVARCHAR(MAX) = 'The Microsoft "business analysis" software';

SELECT
    CASE 
        WHEN ft.special_term = 'Noise Word' THEN 'Noise Word'
        ELSE 'Exact Match'
    END AS special_term,
    CASE
        WHEN ft.special_term = 'Noise Word' THEN LOWER(t.Term)
        ELSE t.Term
    END AS display_term
FROM dbo.ParseQuotedString(@input) t
CROSS APPLY (
    SELECT TOP 1 special_term, display_term
    FROM sys.dm_fts_parser('"' + t.Term + '"', 1033, 0, 0)
    WHERE display_term <> ''
) ft
ORDER BY 
    CASE WHEN ft.special_term = 'Noise Word' THEN 0 ELSE 1 END,
    CHARINDEX(t.Term, @input);

执行结果

运行上面的代码后,就能得到你期望的输出:

special_term display_term
------------ ------------
Noise Word   the
Exact Match  microsoft
Exact Match  business analysis
Exact Match  software

注意事项

  • 这个UDF假设引号是成对出现的,如果有未闭合的引号,会把剩余内容当作普通词处理,你可以根据实际需求调整逻辑。
  • STRING_SPLIT是SQL Server 2016及以上版本才支持的函数,如果你的版本更早,需要替换成自定义的字符串拆分函数。
  • 处理噪声词时,我们用LOWER()统一格式,和你的示例结果保持一致。

备注:内容来源于stack exchange,提问作者Lisa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 11:59:28