2014-01-19 3 views
4

다음 문제에 대한 간단한 해결책을 찾기 위해 며칠을 보냈습니다. 도움이 필요합니다. 필자는 기본 키로 recid (계정 번호)와 모든 xml 데이터를 저장하는 xmlrecord라는 두 개의 열이있는 Oracle 테이블을 보유하고 있습니다. SQL 쿼리를 사용하여 응용 프로그램에서 다중 값 항목을 가져온 값을 내보내려고합니다. 데이터 손상을 제외하면 c1 m = "1"이면 항상 해당 c2 m = "1"이고 c3 m = "1"입니다. 테이블이 너무 커서 각 항목을 추출하기 위해 여러 번 칠 수 없으므로 행의 한 액세스에서 xmlrecord를 모두 꺼내야합니다. 내부 조인 (1 = 1) 및 xmltables를 시도했지만 항상 반환 된 데이터 또는 새 행의 각 새 일치에서 NULL로 끝납니다.여러 요소의 Oracle SQL 추출 값

RECID    XMLRECORD 
----------------------------------- 
0000001   <row><c1>test</c1><c2>test2</c2>....</row> 
0000002   <row><c1>test</c1><c2>test2</c2>....</row> 

위의 기록이 있기 때문에 잘 작동합니다 : 최상위 레벨에서 추출 값으로 인해

기본 테이블의 우리의 데이터 구조는 XML의 구조로이 경우에 나를 위해 작동하지 않습니다 다중 valuse 필드가 없습니다. XMLRecord에 저장된 데이터가 같은 때 나는 사투를 벌인거야 어디는 아래 :

<row> 
    <c1>test1</c1> 
    <c1 m=1>test1_2</c1> 
    <c2>test2</c2> 
    <c2 m=1>test2_2</c2> 
    <c3>test3</c3> 
    <c3 m=1>test3_2</c3> 
</row> 

싶습니다 출력의 형식은 다음과 같습니다 :

RECID  Col1  Col2  Col3 
----------------------------------- 
0000003  test1 test2 test3 
0000003  test1_2 test2_2 test3_2 
0000004  test1 test2 test3 
0000004  test1_2 test2_2 test3_2 
+4

문제는 XML 구조가 잘못되었습니다. 같은 맥락에서 정확히 같은 이름을 가진 두 개의 서로 다른 요소가 필연적으로 문제를 일으킬 것입니다. – APC

답변

1

의견을 보내 주셔서 감사합니다.하지만이 인스턴스에서 작동하는 조인을 작성하여 필요한 솔루션을 얻을 수있었습니다. 그것에 대해 좋은 점은 공급 업체가 우리에게 던지는 기록의 수와 상관없이 작동한다는 것입니다. 어떤 경우에는 "m"속성이 최대 9 또는 10까지 실행됩니다.

(1 = 1)에서 일반적인 내부 조인을 사용하고 동적 ID를 기반으로 후속 조인을 작성했습니다. 첫 번째 행에 대한 ID_NUM의 결과는 "c"이고 다음 행은 "c2"입니다.

SELECT 
    t.recid 
    ,t2.VALUE1 
    ,t3.VALUE2 
    ,t4.VALUE3 
FROM t 
INNER JOIN XMLTABLE('/row/c1' 
    PASSING t.xmlrecord 
    ID_NUM VARCHAR(4) path 'concat(substring(ancestor-or-self::*/name(.),1,1), @m)', 
    VALUE1 VARCHAR(20) path '.') t2 
ON (1=1) 
INNER JOIN XMLTABLE('/row/c2' 
    PASSING t.xmlrecord 
    ID_NUM VARCHAR(4) path 'concat(substring(ancestor-or-self::*/name(.),1,1), @m)', 
    VALUE2 VARCHAR(20) path '.') t3 
ON (t2.ID_NUM=t3.ID_NUM) 
INNER JOIN XMLTABLE('/row/c3' 
    PASSING t.xmlrecord 
    ID_NUM VARCHAR(4) path 'concat(substring(ancestor-or-self::*/name(.),1,1), @m)', 
    VALUE3 VARCHAR(20) path '.') t4 
ON (t2.ID_NUM=t4.ID_NUM) 
+0

XMLTABLE! 언젠가이 데이터베이스를 유지하기 위해 오는 사람을 불쌍히 생각합니다 .--). 그러나 가끔 경영진은 "XML"을 듣고 "오, 그래야 사용할 것입니다!"라고 생각합니다. –

0

당신은 extractValue와를 사용할 수 있어야합니다 ()를 기반으로 요소를 선택하는 XPATH 쿼리를 사용합니다.

SELECT RECID 
    , EXTRACTVALUE(XMLRECORD, '/row/c1[@m=''1'']') 
    , EXTRACTVALUE(XMLRECORD, '/row/c2[@m=''1'']') 
    , EXTRACTVALUE(XMLRECORD, '/row/c3[@m=''1'']') 
FROM T 

당신은

SELECT RECID 
    , EXTRACTVALUE(XMLRECORD, '/row/c1[not(@m)]') 
    , EXTRACTVALUE(XMLRECORD, '/row/c2[not(@m)]') 
    , EXTRACTVALUE(XMLRECORD, '/row/c3[not(@m)]') 
FROM T 

와 다음 UNION ALL이 결과 여러 속성을 수 행의 수에 대한 노동 조합을 계속할 수 있었다.

내가 선택한 각 개별 행에 대해 여러 행을 생성하려고하기 때문에 테이블의 전체 검색에서 쉽게 수행 할 수 없을 것이라고 생각합니다.

이것은 관계형 데이터베이스에 XML을 저장하는 것이 좋은 생각 인 이유 중 좋은 예입니다.

XMLTABLE을 사용하여이 작업을 수행하는 방법을 생각해보고 있습니다. 방법을 생각해 보면 대답을 업데이트 할 것입니다.