【问题标题】:SQL Server substring breaking on words, not charactersSQL Server 子字符串在单词而不是字符上中断
【发布时间】:2010-10-17 20:52:20
【问题描述】:

我想在搜索结果中显示不超过 n 个字符的文本字段,以便让用户了解内容。但是,我找不到轻松断词的方法,所以我在断词时只写了一个部分词。

当我想显示:“这个学生还没有提交他最近的几个作业”时,系统可能会显示:“这个学生没有提交他的最后几个作业”

我希望系统显示最多 n 个字符的限制来保存单词,所以我想看看:

“这个学生还没有提交他的最后几个”

是否有可以在 T-SQL 中编写的最接近单词函数,或者当我将结果返回 ASP 或 .NET 时应该这样做吗?

【问题讨论】:

    标签: sql word substring break


    【解决方案1】:

    我建议在数据库之外执行这种逻辑。使用 C#,它可能看起来类似于:

    static string Cut(string s, int length)
    {
        if (s.Length <= length)
        {
            return s;
        }
    
        while (s[length] != ' ')
        {
            length--;
        }
    
        return s.Substring(0, length).Trim();
    }
    

    当然,您可以使用 T-SQL 执行此操作,但这是个坏主意(性能不佳等)。如果你真的需要把它放在数据库中,我会使用基于 CLR 的存储过程。

    【讨论】:

      【解决方案2】:

      我在this site上找到了答案并修改了:

      • 演员表 (150) 必须大于您返回的字符数 (100)

        LEFT (Cast(myTextField As varchar(150)), CHARINDEX(' ', CAST(fl​​ag_myTextField AS VARCHAR(150)), 100) ) 作为 myTextField_short

      【讨论】:

        【解决方案3】:

        我不确定这会运行多快,但它会起作用....

        DECLARE @Max  int
        
        SET @Max=??
        
        SELECT
           REVERSE(RIGHT(REVERSE(LEFT(YourColumnHere,@Max)),@Max- CHARINDEX(' ',REVERSE(LEFT(YourColumnHere,@Max)))))
            FROM YourTable
            WHERE X=Y
        

        【讨论】:

          【解决方案4】:

          如果必须在 T-SQL 中进行:

          DECLARE @t VARCHAR(100)
          SET @t = 'This student has not submitted his last few assignments'
          
          SELECT LEFT(LEFT(@t, 50), LEN(LEFT(@t, 50)) - CHARINDEX(' ', REVERSE(LEFT(@t, 50))))
          

          它不会非常慢,但肯定会比在表示层中慢。

          除此之外 - 仅删除单词并为更长的字符串附加省略号也不是坏选择。这样,至少所有截断的字符串都具有相同的长度,如果您正在格式化为固定宽度的输出,这可能会派上用场。

          【讨论】:

            【解决方案5】:

            我同意在数据库之外执行此操作,这样具有不同长度限制的其他应用程序可以自行决定显示/隐藏什么。也许这可以作为数据库调用的参数。

            这里是一个快速解决方案:

            DECLARE @OriginalData NVARCHAR(MAX)
                ,@ReversedData NVARCHAR(MAX)
                ,@MaxLength INT 
                ,@DelimiterPosition INT ;
            
            SELECT @OriginalData = 'This student has not submitted his last few assignments'
                ,@MaxLength = 45;
            
            SET @ReversedData = REVERSE(
                                    LEFT(@OriginalData, @MaxLength)
                                );
            
            SET @DelimiterPosition = CHARINDEX(' ', @ReversedData);
            
            PRINT LEFT(@OriginalData, @MaxLength - @DelimiterPosition);
            
            /*
            This student has not submitted his last few assignments
            1234567890123456789012345678901234567890123456789012345
            */
            

            【讨论】:

              【解决方案6】:

              我也不建议这样做,但如果你必须这样做,你可以这样做:

              DECLARE @text nvarchar(max);
              DECLARE @end_char int;
              SELECT @text  = 'This student has not submitted his last few assignments', @end_char = 50 ;
              
              WHILE @end_char > 0 AND SUBSTRING( @text, @end_char+1, 1 ) <> ' '
                  SET @end_char = @end_char - 1
              
              SELECT @text = SUBSTRING( @text, 1, @end_char ) ;
              
              SELECT @text
              

              【讨论】:

                【解决方案7】:

                我想补充一下已经提供的解决方案,断字逻辑比表面上看起来要复杂得多。要做到这一点,您将需要为单词的构成定义许多规则。考虑以下几点:

                • 空格 - 无需多想。
                • 连字符 - 这取决于。 过度曝光可能,重新制作动画可能不会。那么像01-02-1985这样的日期呢?
                • 周期 - 无需多想。哦,等等,myemail@myisp.com$79.95 中的那个呢?
                • 逗号 - 在诸如 1,239 之类的数字中不是,但在句子中是。
                • 撇号 - O'Reily 不,SQL 是“企业”数据库工具 是。
                • 特殊字符单独构成单词吗?:在第1项:购买TP中,冒号算作单词吗?

                【讨论】:

                • 当然。我想这就是普通数据网格做删减法的原因。
                猜你喜欢
                • 2021-02-15
                • 2021-11-23
                • 2019-02-13
                • 1970-01-01
                • 1970-01-01
                • 2019-01-03
                • 2018-03-17
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多