- 전체
- Sample DB
- database modeling
- [표준 SQL] Standard SQL
- G-SQL
- 10-Min
- ORACLE
- MS SQLserver
- MySQL
- SQLite
- postgreSQL
- 데이터아키텍처전문가 - 국가공인자격
- 데이터 분석 전문가 [ADP]
- [국가공인] SQL 개발자/전문가
- NoSQL
- hadoop
- hadoop eco system
- big data (빅데이터)
- stat(통계) R 언어
- XML DB & XQuery
- spark
- DataBase Tool
- 데이터분석 & 데이터사이언스
- Engineer Quality Management
- [기계학습] machine learning
- 데이터 수집 및 전처리
- 국가기술자격 빅데이터분석기사
- 암호화폐 (비트코인, cryptocurrency, bitcoin)
XML DB & XQuery [SQL] XQuery로 XML Data에 접근하기
2016.11.29 20:25
[SQL] XQuery로 XML Data에 접근하기
XQuery는 XML을 조회한다는 개념에서 한발 더 나아가 직접 XML Data에 접근할 수 있도록 해줍니다. 이때 어떠한 방식으로 접근하느냐에 따라 3가지 형식으로 나뉩니다.
우선 XQuery를 사용하기 전에 먼저 Sample XML Data를 만든 후 이 XML Data를 대상으로 XQuery를 적용시켜 보도록 하겠습니다.
| Declare @MyXml Xml; Set @MyXml = ' < TopEle> < Department ID="1"> <Names Nm="Engineering"> <Group> <Name>Research and Development</Name> </Group> </Names> < /Department> < Department ID="2"> <Names Nm="Tool Design"> <Group> <Name>Research and Development</Name> </Group> </Names> < /Department> < Department ID="3"> <Names Nm="Sales"> <Group> <Name>Sales and Marketing</Name> </Group> </Names> < /Department> < /TopEle>'; |
1. query
XML Data의 요소를 얻어오는데 사용되는 method입니다.
| Select @MyXml.query('/TopEle[1]/Department[2]'); |
Data형식이 XML이면 그것이 변수든 Column이든 상관없이 XQuery를 적용시킬 수 있습니다. 위에서는 @MyXml 변수에 XQuery의 query를 적용시켜 원하는 요소를 가져오도록 하였습니다.
먼저 /TopEle[1]을 통해 첫번째 TopEle요소의 하위 Department요소중 두번째 요소(/Department[2])내용을 가져오도록 합니다. 보시는 바와 같이 각 요소는 '/'문자로 구분하며 요소의 순서는 []안에 지정합니다.

이번에는 변수를 사용하여 XML문서내에 있는 각 Name의 요소값을 가져와 보겠습니다.
| Select @MyXml.query('for $s in /TopEle/Department/Names/Group/Name return data($s)'); |
query내에 있는 for는 반복을 의미합니다. 즉, XML의 /Top /TopEle/Department/Names/Group/Name요소를 반복적으로 모두 확인하여 변수 $s에 넣고(data($s)) 그 결과를 출력하도록 하는 것입니다.
| 주의 : XQuery사용시 대/소문자를 명확히 구분합니다. 예를 들어 for를 For라고 하면 오류가 발생합니다. |
이번에는 요소의 값이 아니라 속성의 값을 가져와 보도록 하겠습니다.
| Select @MyXml.query('for $s in /TopEle/Department/@ID return data($s)'); Select @MyXml.query('for $s in /TopEle/Department/Names/@Nm return data($s)'); |
첫번째 XQuery에서는 /TopEle/Department의 ID속성값을 가져오도록 하였고 두번째 XQuery에서는 /TopEle/Department/Names요소의 Nm속성값을 가져오도록 하였습니다.
여기서 '/'는 요소를, '@'는 속성을 의미합니다.

또한 XQuery는 XML Data에서 다음처럼 조건에 맞는 내용만 가져올 수도 있습니다.
| Select @MyXml.query('for $s in /TopEle/Department[@ID eq "2"] return $s'); |
/TopEle/Department요소의 ID속성을 찾아서 값이 2인것만([@ID eq "2"]) 가져오도록 합니다. (XQuery조건문으로 일치하는 값을 지정할 수 있도록 합니다.)
| 참고 : Data($s)를 통해서 값을 가져오는 경우는 해당 변수에 특정 값이 존재할때만 가능합니다. 위에서 제시된 예제는 특정 값이 아니라 XML Data자체이므로 data()를 쓰지 않습니다. |

다음은 다른 XML구문을 추가하여 조회하는 예제입니다.
| Select @MyXml.query('for $s in /TopEle/Department return <myXml><NewValue>{data($s/@ID)}</NewValue><NewString>{data($s/Names/@Nm)}</NewString></myXml>'); |
XQuery결과에 상위 <myXml>요소를 추가하고 각 값마다 <NewValue>요소와 <NewString>요소를 추가하여 XML형태로 결과값을 반환하도록 하고 있으며 동시에 두가지 값을 가져오는 방법도 제시하고 있습니다.
이때 주목해야할 부분이 있는데 두번째 data($s/Names/@Nm)부분을 보시면 for에서 in다음에 /TopEle/Department요소를 지정하여 궁극적으로는 Nmes요소의 Nm속성값을 가져올 수 없을지도 모르지만 이렇게 값을 반환하는 부분에서 하위 요소와 속성을 지정하면(/Names/@Nm) 해당 요소와 속성의 값을 가져올 수 있게 됩니다.

2. value
query는 XML data내에서 각 요소자체를 주출하는 역활을 하지만 value는 요소가 아닌 값만을 가져올 수 있도록 합니다.
| Select @MyXml.value('(/TopEle/Department[3])[1]', 'Char(50)'); |
TopEle전체요소중에서 Department세번째 요소에 있는 첫번째 값을 Char(50) Data형으로 가져옵니다.

value를 사용하면 단순히 값을 가져오는것 이외에 실제 값이 있는가 없는가를 판단할 수도 있습니다.
| Select @MyXml.value('some $s in /TopEle/Department/Names satisfies $s/@Nm="Sales"', 'Char(50)'); |
some을 통해 /TopEle/Department/Names요소의 Nm속성값에 "Sales"가 있으면 true 없으면 false를 반환합니다. (비교자는 satisfies를 사용합니다.)

값을 비교하여 있는지 없는지 판단하는 것은 some이외에 every도 있습니다. some은 값 비교시에 해당 값이 있는 요소가 하나라도 일치하면 true가 되지만 every는 전 요소가 모두 주어진 조건에 일치해야만 true가 됩니다.
| Select @MyXml.value('every $s in /TopEle/Department/Names satisfies $s/@Nm="Sales"', 'Char(50)'); |
Nm속성이 "Sales"라고 되어 있는건 Department/Names의 세번째 요소에서만 일치하므로 결과는 false입니다.

3. exist
values로는 값이 있는지 없는지를 확인할 수 있지만 exist는 요소자체가 있는지 없는지를 판단할 수 있습니다.
| Select @MyXml.exist('/TopEle/Department'); |
/TopEle요소 하위에 Department요소가 있는지 판단한 후 있으면 1 없으면 0을 반환합니다.

4. modify
XML에 접근하여 실제 XML Data를 추가/변경/삭제 할 수 있는 mothod입니다.
(1) 추가
| Set @MyXml.modify('insert <newstart>spadework</newstart> as first into /'); Set @MyXml.modify('insert <newend>spadework</newend> as last into /'); |
< newstart>spadework</newstart>요소와 값을 해당 XML Data의 가장 처음(as first into)에 추가하고 <newend>spadework</newend>를 해당 XML Data의 가장 마지막(as last into)에 추가합니다.

| Set @MyXml.modify('insert <TopEle mytag="new"/> as first into /TopEle[1]'); |
< TopEle mytag="new"/>요소와 속성을 TopEle요소의 처음부분에 추가합니다.

| Set @MyXml.modify('insert <TopEle mytag="new"/> as last into /TopEle[1]/Department[3]'); |
< TopEle mytag="new"/>요소와 속성을 TopEle/Department 3번째 요소의 마지막에 추가합니다.

(2) 변경
| Set @MyXml.modify('replace value of /TopEle[1]/Department[3]/Names[1]/@Nm with "abc"'); |
replace value of 를 통해 TopEle/Department 세번째요소의 Names요소에서 Nm속성값을 abc로 변경합니다.

(3) 삭제
| Set @MyXml.modify('delete /TopEle[1]/Department[2]'); |
delete를 통해 /TopEle/Department 2번째 요소 전체를 삭제하도록 합니다.

광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
댓글 0
| 번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
|---|---|---|---|---|
| 공지 | 오라클 기본 샘플 데이터베이스 | 졸리운_곰 | 2014.01.02 | 86174 |
| 공지 | [SQL컨셉] 서적 "SQL컨셉"의 샘플 데이타 베이스 SAMPLE DATABASE of ORACLE | 가을의 곰을... | 2013.02.10 | 78664 |
| 공지 | [G_SQL] Sample Database | 가을의 곰을... | 2012.05.20 | 95397 |

