0

我在阅读的书中遇到了一些代码,这些代码让我质疑SUBSTRING()函数的行为。该代码应该搜索 NYSIIS 替换表(语音编码示例)并根据表中的位置“结束”“中间”或“开始”替换输入字符串的中间“N-gram”。摘录如下:

NYSIIS 替换表:

位置 NGram 更换

中AA
中 AW AA
中 EA
中 EV 自动对焦
中 EW AA
中IA
USE [AdventureWorks]

DECLARE @Result NVARCHAR(100) = N'NEVADA';

DECLARE @Replacement NVARCHAR(10);

DECLARE @i INT;

SET @i = 1;

WHILE @i <= LEN (@Result)

BEGIN

    SET @Replacement = NULL;

    -- Grab the middle-of-name replacement n-gram

    SELECT TOP(1)  @Replacement = Replacement                   
    FROM dbo.NYSIIS_Replacements                         
    WHERE Location = N'Mid'
        AND SUBSTRING(@Result, @i, LEN(NGram)) = NGram
    ORDER BY LEN(NGram) DESC;


    SET @Replacement = COALESCE(@Replacement, SUBSTRING(@Result, @i, 1));   


    -- If we found a replacement, apply it

    SET @Result = STUFF(@Result, @i, LEN(@Replacement), @Replacement) 

    -- Move on to the next n-gram

    SET @i = @i + COALESCE(LEN(@Replacement), 1);


END;

SELECT @Result;

SUBSTRING()函数遇到 2 个可能的匹配时,以“NEVADA”为例(表中的“E”和“EV”)它如何“知道”使用 2 个字母的字符串而不是一个?这是预期的行为SUBSTRING()吗?

我假设该@Replacement变量将同时包含“A”和“AF”,但在调试时它似乎只在第一次迭代中包含“N”,在第二次迭代中包含“AF”。

我也无法理解为什么TOP并且ORDER BY被包含在这个例子中。将它们注释掉会产生相同的结果。

4

1 回答 1

0

ORDER BY子句使用模式的长度并按降序排序,因此最长的匹配将首先出现。该TOP子句将结果限制在第一行。删除该ORDER BY子句会使结果不可预测。

COALESCE用于设置@Replacement替换模式,或者如果没有找到模式匹配,则设置为字符串中位置@i的字符。@Result

于 2012-09-03T01:19:45.213 回答