SQL Server substring breaking on words, not characters

北战南征 提交于 2019-12-12 13:57:00

问题


I'd like to show no more than n characters of a text field in search results to give the user an idea of the content. However, I can't find a way to easily break on words, so I wind up with a partial word at the break.

When I want to show: "This student has not submitted his last few assignments", the system might show: "This student has not submitted his last few assig"

I'd prefer that the system show up to the n character limit where words are preserved, so I'd like to see:

"This student has not submitted his last few"

Is there a nearest word function that I could write in T-SQL, or should I do that when I get the results back into ASP or .NET?


回答1:


I agree with doing this outside of the database that way other applications with different length restrictions can make their own decisions on what to show/hide. Perhaps that can be a parameter to the database call though.

Here's a quick stab at a solution:

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
*/



回答2:


I recommend doing that kind of logic outside database. With C# it could look similar to this:

static string Cut(string s, int length)
{
    if (s.Length <= length)
    {
        return s;
    }

    while (s[length] != ' ')
    {
        length--;
    }

    return s.Substring(0, length).Trim();
}

Of cause you could do this with T-SQL, but that is bad idea (bad performance etc.). If you really need to put it inside DB I would use CLR-based stored procedure instead.




回答3:


I'd like to add to the solutions already offered that word breaking logic is a lot more complicated than it seems on the surface. To do it well you are going to need to define a number of rules for what constitutes a word. Consider the following:

  • Spaces - No brainer.
  • Hyphens - Well that depends. In Over-exposed proably, in re-animated probably not. Then what about dates such as 01-02-1985?
  • Periods - No brainer. Oh wait, what about the one in myemail@myisp.com or $79.95?
  • Commas - In numbers such as 1,239 no, but in sentences yes.
  • Apostrophes - In O'Reily no, in SQL is an 'Enterprise' Database tool yes.
  • Do special characters alone constitute words?: In Item 1 : Buy TP is the colon counted as a word?



回答4:


If you must do it in 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))))

It will not be catastrophically slow, but it will definitely be slower than doing it in the presentation layer.

Other than that — just cutting off the word and appending an ellipsis for longer strings is no bad option either. This way at least all truncated strings have the same length, which might come in handy if you are formatting for a fixed-width output.




回答5:


I found an answer on this site and modified it:

  • the cast (150) must be greater than the number of characters you're returning (100)

    LEFT (Cast(myTextField As varchar(150)), CHARINDEX(' ', CAST(flag_myTextField AS VARCHAR(150)), 100) ) AS myTextField_short




回答6:


I'm not sure how fast this will run, but it will work....

DECLARE @Max  int

SET @Max=??

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



回答7:


I wouldn't advice to do that either, but if you must, you can do something like this:

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


来源:https://stackoverflow.com/questions/722418/sql-server-substring-breaking-on-words-not-characters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!