Печать маркера перед каждым предложением + новая строка после каждого предложения SQL - PullRequest
3 голосов
/ 28 ноября 2011

У меня есть текст вроде: Приговор один.Приговор второй.Предложение три.

Я хочу, чтобы оно было:

  • Предложение одно.
  • Предложение два.
  • Предложение три.

Я предполагаю, что могу заменить '.' на '.' + char(10) + char(13), но как я могу использовать пули?Символ «•» работает нормально при печати вручную. Я просто не знаю, как маркировать каждое предложение, включая первое.

Ответы [ 2 ]

4 голосов
/ 28 ноября 2011
-- Initial string
declare @text varchar(100)
set @text = 'Sentence one. Sentence two. Sentence three.'

-- Setting up replacement text - new lines (assuming this works) and bullets ( char(149) )
declare @replacement varchar(100)
set @replacement = '.' + char(10) + char(13) + char(149)

-- Adding a bullet at the beginning and doing the replacement, but this will also add a trailing bullet
declare @processedText varchar(100)
set @processedText = char(149) + ' ' + replace(@text, '.', @replacement)

-- Figure out length of substring to select in the next step
declare @substringLength int
set @substringLength = LEN(@processedText) - CHARINDEX(char(149), REVERSE(@processedText))

-- Removes trailing bullet
select substring(@processedText, 0, @substringLength)

Я тестировал здесь - http://data.stackexchange.com/stackoverflow/qt/119364/

Я должен отметить, что выполнение этого в T-SQL кажется неправильным.T-SQL предназначен для обработки данных;любая работа, связанная с презентацией, должна выполняться в коде, который вызывает этот T-SQL (C # или что вы используете).

1 голос
/ 28 ноября 2011

Вот мой чрезмерный подход, но я чувствую, что это достаточно надежный подход. Он сочетает в себе классические методы решения проблем SQL числовых таблиц для разрезания строк и использование FOR XML для объединения линий разделения обратно. Код длинный, но единственное место, которое вам нужно отредактировать, - это раздел SOURCE_DATA.

Никаких стуков в подходе @Jeremy Wiggins, но я предпочитаю мой, так как он хорошо поддается подходу, основанному на множествах, в дополнение к довольно эффективному коду.

-- This code will rip lines apart based on @delimiter
-- and put them back together based on @rebind
DECLARE 
    @delimiter char(1)
,   @rebind varchar(10);

SELECT
    @delimiter = '.'
,   @rebind = char(10) + char(149) + ' ';

;
-- L0 to L5 simulate a numbers table
-- http://billfellows.blogspot.com/2009/11/fast-number-generator.html
WITH L0 AS
(
    SELECT
        0 AS C
    UNION ALL
    SELECT
        0
)
, L1 AS
(
    SELECT
        0 AS c
    FROM
        L0 AS A
        CROSS JOIN L0 AS B
)
, L2 AS
(
    SELECT
        0 AS c
    FROM
        L1 AS A
        CROSS JOIN L1 AS B
)
, L3 AS
(
    SELECT
        0 AS c
    FROM
        L2 AS A
        CROSS JOIN L2 AS B
)
, L4 AS
(
    SELECT
        0 AS c
    FROM
        L3 AS A
        CROSS JOIN L3 AS B
)
, L5 AS
(
    SELECT
        0 AS c
    FROM
        L4 AS A
        CROSS JOIN L4 AS B
)
, NUMS AS
(
    SELECT
        ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS number
    FROM
        L5
)
, SOURCE_DATA (ID, content) AS
(
    -- This query simulates your input data
    SELECT 1, 'Sentence one. Sentence two. Sentence three.'
    UNION ALL SELECT 7, 'In seed time learn, in harvest teach, in winter enjoy.Drive your cart and your plow over the bones of the dead.The road of excess leads to the palace of wisdom.Prudence is a rich, ugly old maid courted by Incapacity.He who desires but acts not, breeds pestilence.'
)
, MAX_LENGTH AS
(
    -- this query is rather important. The current NUMS query generates a 
    -- very large set of numbers but we only need 1 to maximum lenth of our
    -- source data. We can take advantage of a 2008 feature of letting
    -- TOP take a dynamic value
    SELECT TOP (SELECT MAX(LEN(SD.content)) AS max_length FROM SOURCE_DATA SD)
        N.number
    FROM
        NUMS N
)
, MULTI_LINES AS
(
    -- This query will make many lines out a single line based on the supplied delimiter
    -- Need to retain the ID (or some unique value from original data to regroup it
    -- http://www.sommarskog.se/arrays-in-sql-2005.html#tblnum
    SELECT 
        SD.ID
    ,   LTRIM(substring(SD.content, Number, charindex(@delimiter, SD.content + @delimiter, Number) - Number)) + @delimiter AS lines
    FROM
        MAX_LENGTH
        CROSS APPLY
            SOURCE_DATA SD
    WHERE
        Number <= len(SD.content)
        AND substring(@delimiter + SD.content, Number, 1) = @delimiter
)
, RECONSITITUE (content, ID) AS
(
    -- use classic concatenation to put it all back together
    -- using CR/LF * (space) as delimiter
    -- as a correlated sub query and joined back to our original table to preserve IDs
    -- https://stackoverflow.com/questions/5196371/sql-query-concatenating-results-into-one-string
    SELECT DISTINCT 
    STUFF
    ( 
        (
            SELECT @rebind + M.lines
            FROM MULTI_LINES M
            WHERE M.ID = ML.ID
            FOR XML PATH('')
        )
    , 1
    , 1
    , '')
    ,   ML.ID
    FROM 
        MULTI_LINES ML
)
SELECT 
    R.content
,   R.ID
FROM 
    RECONSITITUE R

Результаты

content                                                       ID
-----------------------------------------------------------   ---
• In seed time learn, in harvest teach, in winter enjoy.
• Drive your cart and your plow over the bones of the dead.
• The road of excess leads to the palace of wisdom.
• Prudence is a rich, ugly old maid courted by Incapacity.
• He who desires but acts not, breeds pestilence.             7
• Sentence one.
• Sentence two.
• Sentence three.                                             1

(2 row(s) affected)

Ссылки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...