2013-04-23 84 views
1

我對處理溢出任意限制的文本字段的語法有疑問。將文本字段溢出至多行

我有以下表和數據:

CREATE TABLE [dbo].[Notes](
[Note] [varchar](max) NULL, 
[Code1] [varchar](50) NULL, 
[Code2] [varchar](50) NULL 
) 

INSERT INTO Notes (Code1,Code2,Note) 

VALUES 
('JAD','XFR','Lorem ipsum dolor sit amet'), 
('JAD','X400','Lorem ipsum '), 
('JAD','X700','Lorem ') 

我的任務是進行查詢,將返回所有的數據表中,但接收系統對備註字段字符限制(真正的系統只接受255個字符,爲了簡潔,我在這裏縮短了它)。

爲了處理這個限制,我需要的是當筆記字段溢出限制時,查詢應該向包含筆記文本的下一部分的輸出添加另一行,但是行的前兩個字段應該重複前兩個代碼。

下面的查詢完成任務,但它非常醜陋,有侷限性。我希望能找到一個更加優雅的解決方案來解決這個可怕的問題。

此外,接收系統是客戶端系統。我不明白爲什麼地球上它想要一個數據轉儲的格式,這個靈魂非常愚蠢,所以請不要問。

DECLARE @TEMP TABLE (
    RowNumber INT, 
    Depth INT, 
    Code1 VARCHAR(50), 
    Code2 VARCHAR(50), 
    Note VARCHAR(MAX)  
) 

INSERT INTO @TEMP 
SELECT 
row_number() OVER (ORDER BY Code1), 
1, 
Code1, 
Code2, 
left(Note,(5 - len(Code1) + len(Code2))) 
FROM Notes 

UNION ALL 

SELECT 
row_number() OVER (ORDER BY Code1), 
2, 
Code1, 
Code2, 
substring(Note,(5 - len(Code1) + len(Code2))+1,5) 
FROM Notes 


UNION ALL 

SELECT 
row_number() OVER (ORDER BY Code1), 
3, 
Code1, 
Code2, 
substring(Note,(5 - len(Code1) + len(Code2))+6,5) 
FROM Notes 


UNION ALL 

SELECT 
row_number() OVER (ORDER BY Code1), 
4, 
Code1, 
Code2, 
substring(Note,(5 - len(Code1) + len(Code2))+11,5) 
FROM Notes 



UNION ALL 

SELECT 
row_number() OVER (ORDER BY Code1), 
5, 
Code1, 
Code2, 
substring(Note,(5 - len(Code1) + len(Code2))+16,5) 
FROM Notes 



Select 
Code1, 
Code2, 
Note 
FROM @TEMP AS T 
WHERE NOTE <> '' 
ORDER BY RowNumber, Depth 

輸出應該是這樣的:

Code1 Code2 Note 
JAD  XFR  Lorem 
JAD  XFR  ipsu 
JAD  XFR  m dol 
JAD  XFR  or si 
JAD  XFR  t ame 
JAD  X400 Lorem 
JAD  X400 ipsum 
JAD  X700 Lorem 
+0

我不想以這種方式存儲它。這只是爲客戶端系統生成輸出的代碼。在每個255個字符之後使用cr/lf的唯一問題是,它不會重複前面的列,這在生產應用程序中包含標識信息,可能是爲了讓接收系統能夠將所有這些東西重新組合在一起。 – 2013-04-23 22:29:28

+0

除了前面描述的255個字符限制之外,我不確定我是否理解這個問題。該字符數是我給出的限制。過去,該領域必須溢出到一個新的行。 我認爲子字符串函數可能是一個混淆點,我不完全確定每行包含的結束限制是什麼,無論我的限制是255(code1 + code2)還是255 + code1 + code2。 但我認爲這個問題的本質是相同的只是對算法的一點點調整。 – 2013-04-23 22:33:07

+0

啊,我明白了。對不起,該字段是VARCHAR(MAX) – 2013-04-23 22:36:10

回答

2

如何:

WITH Note1(note, code1, code2, start, orig) AS 
(
    SELECT SUBSTRING(Note, 1, 5), Code1, Code2, 1, Note 
    FROM Notes 

    UNION ALL 

    SELECT SUBSTRING(orig, start + 5, 5), Code1, Code2, start + 5, orig 
    FROM Note1 
    WHERE LEN(SUBSTRING(orig, start + 5, 5)) > 0 
) 
SELECT code1, code2, note FROM Note1 
ORDER BY Note1.code2, Note1.start 

我承認,我的命名吮吸:)通過將所有的數據到一個

+4

如果「備註」列真的接近2 GB ... – 2013-04-23 22:40:21

+0

哇,那麼您將超出遞歸限制(以及可能的性能容限)哇,這似乎是一個非常好的解決方案。我只知道它是如何工作的,因爲我不熟悉CTE遞歸。你能總結一下嗎? – 2013-04-23 22:51:53

+0

好吧,我所以我想到了這是如何工作的,並且我能夠很快適應它,讓我後面的人們能夠支持我。非常感謝這個解決方案。 – 2013-04-23 23:59:06

0

開始登臺表。然後在您的真實表格中進行一系列插入並更新到臨時表格。

確保實數表具有相應的主鍵和外鍵,以便以後可以重新組合文本。