每个句子前面打印子弹+每个句子后面的新行SQL

时间:2011-11-28 00:52:30

标签: sql sql-server-2008

我有一个文字:句子一。句子二。三句。

我希望它是:

  • 一句话。
  • 判刑二。
  • 判刑三。

我认为我可以用'.'替换'.' + char(10) + char(13),但我怎样才能使用子弹? '•'字符如果手动打印就可以正常工作我只是不知道如何弹出每个句子,包括第一个句子。

2 个答案:

答案 0 :(得分:4)

-- 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 :(得分:1)

这是我的过分方法,但我觉得这是一个相当坚实的方法。它结合了用于字符串分割的数字表的经典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)

参考