2017-04-17 18 views
0

有一個表中所包括的IDNotes,LEN(注),和LEN/60SQL服務器:拆分文本字段成基於LEN規則多行

我需要它分解成LEN = 60塊,添加一個新的「LINE」列,每行增加1。

所以:

1 | Super long text of 150 characters | 150 | 3 

變爲:

- 1 | 1 | Super long text of 150 
- 1 | 2 | characters is much more 
- 1 | 3 | manageable! 

我創建了LEN和LEN/60數據的情況下,段值將是某種形式的循環語句非常有用。

遞歸CTE,循環,變量 - 在這一點上,我對任何事情都是開放的!

感謝您的幫助!

+3

恕我直言,你正在使數據存儲和數據檢索比他們需要更難。 SQL服務器可以處理長文本,並且如果它全部在一個記錄中,在應用程序中讀取和解析它會容易得多。 –

+0

完全同意你,仁 - 不幸的是,應用程序正在推動這個解決方案,因爲它是爲了處理多行項目,每行長度不超過60個字符。 – chaseman1973

回答

1

是的。 CTE是答案。請試試這個。

WITH cte_base AS(SELECT ID 
        , 1 AS IDLN 
        , LTRIM(RTRIM(Notes)) AS Notes 
        , 1 AS Rownum 
       FROM yourtable 
), cte_re AS (SELECT Id 
        , IDLN 
        , 1 AS StartPos 
        , CAST(60 - CHARINDEX(' ', REVERSE(LEFT(SUBSTRING(Notes, 1, 60) + ' ', 60))) AS INT) StringLen 
       FROM cte_base 
       WHERE Rownum =1 
       UNION ALL 
       SELECT r.Id 
        , r.IDLN + 1 
        , StartPos + StringLen + 1 
        , CAST(60 - CHARINDEX(' ', REVERSE(LEFT(SUBSTRING(b.Notes, StartPos + StringLen + 1, 60) + ' ', 60))) AS INT) 
       FROM CTE_re r 
       INNER JOIN cte_base b 
        ON b.Id = r.Id and b.rownum = 1 
       WHERE StartPos + StringLen <= DATALENGTH(b.Notes) 
)  
SELECT r.Id 
    , r.IDLN 
    , UPPER(SUBSTRING(b.Notes, r.StartPos, r.StringLen)) AS Notes 
FROM cte_re r 
INNER JOIN cte_base b 
ON r.Id = b.Id; 
+0

非常感謝,溫迪!這是SUPER關閉,但我遇到了兩個問題: 1:任何超過1段的行都會產生額外的「空白」行。因此,ID爲1771的長度爲110的應該導致2行(IDLN 1和2),但結果爲4,最後2個空白註釋值爲 2:如果我讓您的代碼在未指定ID的情況下運行,則會收到Msg 530,「最大遞歸100在語句完成之前已經耗盡」錯誤。 你能幫助我多一點嗎? – chaseman1973

+0

你能提供一些樣本數據嗎? – Wendy