2013-04-23 2 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를 사용하는 유일한 문제는 프로덕션 응용 프로그램에서 식별 정보를 포함하는 앞의 열을 반복하지 않는다는 것입니다. 아마도 수신 시스템이 이러한 모든 정보를 다시 집어 넣을 수 있습니다. –

+0

앞에서 설명한 255 자 제한 외에도이 질문을 이해할 수 있을지 확신 할 수 없습니다. 그 문자 수는 내가받은 한도입니다. 과거에는 필드가 새로운 행으로 오버 플로우되어야합니다. 서브 문자열 기능이 혼란의 한 지점 일 수 있다고 생각합니다. 내 한계가 255 (code1 + code2) 또는 255 + code1 + code2가 될지 여부에 관계없이 행마다 최종 제한이 포함되는지 확실하지 않습니다. 그러나 질문의 ​​본질은 산술을 조금만 수정해도 마찬가지라고 생각합니다. –

+0

아, 알겠습니다. 죄송합니다. 입력란은 VARCHAR (MAX) –

답변

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

Note 열이 실제로 2GB에 접근 할 수 있으면 재귀 제한 (및 성능 허용 오차도)을 초과하게됩니다 ... –

+0

와우, 정말 좋은 해결책 인 것 같습니다. 나는 CTE 재귀에 정통하지 않기 때문에 그것이 어떻게 작동하는지에 관한 막연한 생각을 가지고있다. 요약 해 주시겠습니까? –

+0

좋아, 나는 이것이 어떻게 작동하는지 알아 냈고, 나에게 그것을 적응시킬 수 있었고, 나를 따르는 사람들이 나를 따라갈 수있는 방식으로 꽤 빨리 필요로했다.이 솔루션에 대해 대단히 감사드립니다. –

0

시작을에 모든 데이터를 가져 와서 스테이징 테이블. 그런 다음 실제 테이블에 일련의 삽입을 수행하고 스테이징 테이블을 업데이트하십시오.

이후에 텍스트를 다시 어셈블 할 수 있도록 실제 테이블에 적절한 기본 키와 외래 키가 있는지 확인하십시오.