Разрыв подстроки SQL Server для слов, а не символов - PullRequest
3 голосов
/ 06 апреля 2009

Я бы хотел, чтобы в результатах поиска отображалось не более n символов текстового поля, чтобы дать пользователю представление о содержании. Однако я не могу найти способ легко разбить слова, поэтому в конце получаю частичное слово.

Когда я хочу показать: «Этот студент не представил свои последние несколько заданий», система может показать: «Этот студент не представил свои последние несколько заданий»

Я бы предпочел, чтобы система показывала до n символов, где сохраняются слова, поэтому я хотел бы видеть:

"Этот студент не представил свои последние несколько"

Есть ли функция ближайшего слова, которую я мог бы написать в T-SQL, или я должен сделать это, когда получу результаты обратно в ASP или .NET?

Ответы [ 7 ]

1 голос
/ 06 апреля 2009

Я согласен с этим за пределами базы данных, чтобы другие приложения с различными ограничениями по длине могли принимать решения о том, что показывать / скрывать. Возможно, это может быть параметром для вызова базы данных, хотя.

Вот быстрый ответ на решение:

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
*/
1 голос
/ 06 апреля 2009

Я хотел бы добавить к уже предложенным решениям, что логика разбиения по словам намного сложнее, чем кажется на первый взгляд. Чтобы сделать это хорошо, вам нужно будет определить ряд правил, которые составляют слово. Учтите следующее:

  • Пробелы - ежу понятно.
  • Дефисы - Ну, это зависит. В переэкспонирован , вероятно, в реанимирован , вероятно, нет. Тогда как насчет дат, таких как 01-02-1985 ?
  • Периоды - ежу понятно. Ой, подождите, а как насчет myemail@myisp.com или 79,95 ?
  • Запятые - в таких числах, как 1,239 нет, но в предложениях да.
  • Апострофы - в O'Reily нет, в SQL - это инструмент для баз данных 'Enterprise' да.
  • Составляют ли слова одни только символы ?: В Элемент 1: Купить TP считается ли двоеточие словом?
1 голос
/ 06 апреля 2009

Если вы должны сделать это в 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))))

Это не будет катастрофически медленным , но определенно будет медленнее, чем это делается на уровне представления.

Кроме этого & mdash; просто обрезание слова и добавление многоточия для более длинных строк - тоже неплохой вариант. Таким образом, по крайней мере все усеченные строки имеют одинаковую длину, что может пригодиться, если вы форматируете для вывода с фиксированной шириной.

1 голос
/ 06 апреля 2009

Я рекомендую делать такую ​​логику вне базы данных. С 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.

0 голосов
/ 06 апреля 2009

Я бы тоже не советовал это делать, но если нужно, вы можете сделать что-то вроде этого:

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
0 голосов
/ 06 апреля 2009

Я не уверен, насколько быстро это будет работать, но это будет работать ....

DECLARE @Max  int

SET @Max=??

SELECT
   REVERSE(RIGHT(REVERSE(LEFT(YourColumnHere,@Max)),@Max- CHARINDEX(' ',REVERSE(LEFT(YourColumnHere,@Max)))))
    FROM YourTable
    WHERE X=Y
0 голосов
/ 06 апреля 2009

Я нашел ответ на этом сайте и изменил его:

  • приведение (150) должно быть больше количества возвращаемых символов (100)

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

...