13.2.7 LOAD XML 구문
LOAD XML [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name
' [REPLACE | IGNORE] INTO TABLE [db_name
.]tbl_name
[CHARACTER SETcharset_name
] [ROWS IDENTIFIED BY '<tagname
>'] [IGNOREnumber
{LINES | ROWS}] [(field_name_or_user_var
,...)] [SETcol_name
=expr
,...]
LOAD XML
문은 XML 파일에서 테이블에 데이터를 읽습니다. file_name
은 리터럴 문자열로 지정해야합니다. 옵션 ROWS IDENTIFIED BY
절에 tagname
도 문자열 리터럴로 지정하고 꺽쇠 괄호 ( <
및 >
)로 묶어야합니다.
LOAD XML
은 XML 출력 모드에서 mysql 클라이언트의 실행 (즉, --xml
옵션을 사용하여 클라이언트의 시작)을 보완하는 역할을합니다. 테이블에서 XML 파일에 데이터를 쓰려면 시스템 쉘에서 다음과 같은 명령을 사용합니다.
shell> mysql --xml -e 'SELECT * FROM mytable' > file.xml
그 파일을 테이블에 읽기 되돌리려면 LOAD XML INFILE
을 사용합니다. 기본적으로 <row>
요소는 데이터베이스 테이블 행과 동일한 것으로 간주됩니다. 이것은 ROWS IDENTIFIED BY
절을 사용하여 변경할 수 있습니다.
이 문은 다음의 3 가지 XML 형식을 지원합니다.
속성으로 컬럼 이름과 속성 값으로 컬럼 값 :
<
row
column1
= "value1
"column2
= "value2
"... />태그로 컬럼 명과 이러한 태그의 내용으로 컬럼 값 :
<
row
> <column1
>value1
</column1
> <column2
>value2
</column2
> </row
>컬럼 이름은
<field>
태그의name
속성 값은이 태그의 내용 :<row> <field name = '
column1
'>value1
</ field> <field name = 'column2
'>value2
</ field> </ row>이것은 mysqldump와 같은 다른 MySQL 툴에 의해 사용되는 형식입니다.
같은 XML 파일에서 3 개의 모든 형식을 사용할 수 있습니다. 가져 오기 루틴은 각 행의 형식을 자동으로 감지하고 그것을 올바르게 해석합니다. 태그는 태그 또는 속성 이름과 컬럼 이름에 따라 정렬됩니다.
다음 절은 기본적으로 LOAD XML
에 대해 LOAD DATA
에 대한 경우와 동일하게 작동합니다.
LOW_PRIORITY
또는CONCURRENT
LOCAL
REPLACE
또는IGNORE
PARTITION
CHARACTER SET
(
column_or_user_var
,...)SET
이 어구 대한 자세한 내용은 섹션 13.2.6 "LOAD DATA INFILE 구문" 을 참조하십시오.
IGNORE
또는 number
LINESIGNORE
절을 지정하면 XML 파일의 첫 번째 number
ROWSnumber
행이 생략됩니다. 이것은 LOAD DATA
문 IGNORE ... LINES
절에 유사합니다.
이 문이 어떻게 사용되는지를 설명하기 위해 다음과 같이 생성 된 테이블이 있다고합니다.
USE test; CREATE TABLE person ( person_id INT NOT NULL PRIMARY KEY, fname VARCHAR (40) NULL, lname VARCHAR (40) NULL, created TIMESTAMP );
또한이 테이블이 처음에는 비어 있다고합니다.
여기에서 다음과 같은 내용을 가지고 간단한 XML 파일 person.xml
가 있다고합니다.
<? xml version = "1.0"?> <list> <person person_id = "1"fname = "Pekka"lname = "Nousiainen"/> <person person_id = "2"fname = "Jonas"lname = "Oreland"/> <person person_id = "3"> <fname> Mikael </ fname> <lname> Ronström </ lname> </ person> <person person_id = "4"> <fname> Lars </ fname> <lname> Thalmann </ lname> </ person> <person> <field name = "person_id"> 5 </ field> <field name = "fname"> Tomas </ field> <field name = "lname"> Ulin </ field> </ person> <person> <field name = "person_id"> 6 </ field> <field name = "fname"> Martin </ field> <field name = "lname"> Sköld </ field> </ person> </ list>
예제로만이 파일에는 앞에서 설명한 허가 된 각 XML 형식을 나타내고 있습니다.
person.xml
의 데이터를 person
테이블에 가져 오려면 다음 문을 사용할 수 있습니다.
mysql>LOAD XML LOCAL INFILE 'person.xml'
->INTO TABLE person
->ROWS IDENTIFIED BY '<person>';
Query OK, 6 rows affected (0.00 sec) Records : 6 Deleted : 0 Skipped : 0 Warnings : 0
여기에서는 person.xml
가 MySQL 데이터 디렉토리에 존재하는 것을 전제로하고 있습니다. 이 파일이없는 경우 다음과 같은 오류가 발생합니다.
ERROR 2 (HY000) : File '/person.xml'not found (Errcode : 2)
ROWS IDENTIFIED BY '<person>'
어구는 XML 파일의 각 <person>
요소가이 데이터를 가져올 때 테이블의 각 행과 동등하다고 간주되는 것을 나타냅니다. 이 경우,이 test
데이터베이스의 person
테이블입니다.
서버의 응답에서 볼 수 있듯이, test.person
테이블에는 6 행이 임포트되었습니다. 이것은 간단한 SELECT
문에서 확인할 수 있습니다.
mysql> SELECT * FROM person;
+-----------+--------+------------+---------------------+
| person_id | fname | lname | created |
+-----------+--------+------------+---------------------+
| 1 | Kapek | Sainnouine | 2007-07-13 16:18:47 |
| 2 | Sajon | Rondela | 2007-07-13 16:18:47 |
| 3 | Likame | Örrtmons | 2007-07-13 16:18:47 |
| 4 | Slar | Manlanth | 2007-07-13 16:18:47 |
| 5 | Stoma | Nilu | 2007-07-13 16:18:47 |
| 6 | Nirtam | Sklöd | 2007-07-13 16:18:47 |
| 7 | Sungam | Dulbåd | 2007-07-13 16:18:47 |
| 8 | Sreraf | Encmelt | 2007-07-13 16:18:47 |
+-----------+--------+------------+---------------------+
8 rows in set (0.00 sec)
이 섹션의 앞부분에서 설명한 바와 같이 허용되는 3 개의 XML 형식 중 하나 또는 모두를 하나의 파일에 포함 그것을 LOAD XML
을 사용하여 읽을 수 있습니다.
위의 작업과 반대, 즉 MySQL 테이블 데이터의 XML 파일에 덤프는 다음과 같이 시스템 쉘에서 mysql 클라이언트를 사용하여 얻을 수 있습니다.
--xml
옵션을 지정하면 mysql 클라이언트는 그 출력으로 XML 형식을 사용합니다. -e
옵션을 지정하면 클라이언트가 옵션 다음에 나오는 SQL 문을 실행합니다.
shell>mysql --xml -e "SELECT * FROM test.person" > person-dump.xml
shell>cat person-dump.xml
<? xml version = "1.0"?> <resultset statement = "SELECT * FROM test.person"xmlns : xsi = "http://www.w3.org/2001/XMLSchema-instance"> <row> <field name = "person_id"> 1 </ field> <field name = "fname"> Pekka </ field> <field name = "lname"> Nousiainen </ field> <field name = "created"> 2007-07-13 16:18:47 </ field> </ row> <row> <field name = "person_id"> 2 </ field> <field name = "fname"> Jonas </ field> <field name = "lname"> Oreland </ field> <field name = "created"> 2007-07-13 16:18:47 </ field> </ row> <row> <field name = "person_id"> 3 </ field> <field name = "fname"> Mikael </ field> <field name = "lname"> Ronström </ field> <field name = "created"> 2007-07-13 16:18:47 </ field> </ row> <row> <field name = "person_id"> 4 </ field> <field name = "fname"> Lars </ field> <field name = "lname"> Thalmann </ field> <field name = "created"> 2007-07-13 16:18:47 </ field> </ row> <row> <field name = "person_id"> 5 </ field> <field name = "fname"> Tomas </ field> <field name = "lname"> Ulin </ field> <field name = "created"> 2007-07-13 16:18:47 </ field> </ row> <row> <field name = "person_id"> 6 </ field> <field name = "fname"> Martin </ field> <field name = "lname"> Sköld </ field> <field name = "created"> 2007-07-13 16:18:47 </ field> </ row> </ resultset>
다음과 같이 person
의 복사를 작성한 후 덤프 파일을 새로운 테이블에 가져 와서이 덤프가 유효한지 확인 할 수 있습니다.
mysql>USE test;
mysql>CREATE TABLE person2 LIKE person;
Query OK, 0 rows affected (0.00 sec) mysql>LOAD XML LOCAL INFILE 'person-dump.xml'
->INTO TABLE person2;
Query OK, 8 rows affected (0.01 sec) Records: 8 Deleted: 0 Skipped: 0 Warnings: 0 mysql>SELECT * FROM person2;
+-----------+--------+------------+---------------------+ | person_id | fname | lname | created | +-----------+--------+------------+---------------------+ | 1 | Kapek | Sainnouine | 2007-07-13 16:18:47 | | 2 | Sajon | Rondela | 2007-07-13 16:18:47 | | 3 | Likema | Örrtmons | 2007-07-13 16:18:47 | | 4 | Slar | Manlanth | 2007-07-13 16:18:47 | | 5 | Stoma | Nilu | 2007-07-13 16:18:47 | | 6 | Nirtam | Sklöd | 2007-07-13 16:18:47 | | 7 | Sungam | Dulbåd | 2007-07-13 16:18:47 | | 8 | Sreraf | Encmelt | 2007-07-13 16:18:47 | +-----------+--------+------------+---------------------+ 8 rows in set (0.00 sec)
ROWS IDENTIFIED BY '<
어구를 사용하면 같은 XML 파일의 데이터를 정의 다른 데이터베이스 테이블로 가져올 수 있습니다. 이 예제에서는 다음 XML을 포함 tagname
>'address.xml
라는 파일이 있다고합니다.
<? xml version = "1.0"?> <list> <person person_id = "1"> <fname> Robert </ fname> <lname> Jones </ lname> <address address_id = "1"street = "Mill Creek Road"zip = "45365"city = "Sidney"/> <address address_id = "2"street = "Main Street"zip = "28681"city = "Taylorsville"/> </ person> <person person_id = "2"> <fname> Mary </ fname> <lname> Smith </ lname> <address address_id = "3"street = "River Road"zip = "80239"city = "Denver"/> <! - <address address_id = "4"street = "North Street"zip = "37920"city = "Knoxville"/> -> </ person> </ list>
다시 말하지만,이 섹션에서 이전에 정의 된 test.person
테이블을 사용할 수 있습니다. 테이블의 기존 레코드를 모두 클리어 한 후 다음과 같이 그 구조를 표시합니다.
mysql <TRUNCATE person;
Query OK, 0 rows affected (0.04 sec) mysql <SHOW CREATE TABLE person\G
*************************** 1. row ******************** ******* Table : person Create Table : CREATE TABLE`person` ( `person_id` int (11) NOT NULL, `fname` varchar (40) DEFAULT NULL, `lname` varchar (40) DEFAULT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`person_id`) ) ENGINE = MyISAM DEFAULT CHARSET = latin1 1 row in set (0.00 sec)
그런 다음 CREATE TABLE
문을 사용하여 test
데이터베이스에 address
테이블을 만듭니다.
CREATE TABLE address ( address_id INT NOT NULL PRIMARY KEY, person_id INT NULL, street VARCHAR (40) NULL, zip INT NULL, city VARCHAR (40) NULL, created TIMESTAMP );
XML 파일의 데이터를 person
테이블에 가져 오려면 다음과 같이 행이 <person>
요소에 지정되도록 지정하는 다음 LOAD XML
문을 실행합니다.
mysql>LOAD XML LOCAL INFILE 'address.xml'
->INTO TABLE person
->ROWS IDENTIFIED BY '<person>';
Query OK, 2 rows affected (0.00 sec) Records : 2 Deleted : 0 Skipped : 0 Warnings : 0
SELECT
문을 사용하여 레코드를 가져온 것을 확인할 수 있습니다.
mysql> SELECT * FROM person;
+-----------+--------+-------+---------------------+
| person_id | fname | lname | created |
+-----------+--------+-------+---------------------+
| 1 | Robert | Jones | 2007-07-24 17:37:06 |
| 2 | Mary | Smith | 2007-07-24 17:37:06 |
+-----------+--------+-------+---------------------+
2 rows in set (0.00 sec)
XML 파일의 <address>
요소는 person
테이블에 대응하는 컬럼이 없으므로 생략됩니다.
<address>
요소의 데이터를 address
테이블에 가져 오려면 다음과 LOAD XML
문을 사용합니다.
mysql>LOAD XML LOCAL INFILE 'address.xml'
->INTO TABLE address
->ROWS IDENTIFIED BY '<address>';
Query OK, 3 rows affected (0.00 sec) Records : 3 Deleted : 0 Skipped : 0 Warnings : 0
다음과 같은 SELECT
문을 사용하여 데이터를 가져온 것을 확인할 수 있습니다.
mysql> SELECT * FROM address;
+------------+-----------+-----------------+-------+--------------+---------------------+
| address_id | person_id | street | zip | city | created |
+------------+-----------+-----------------+-------+--------------+---------------------+
| 1 | 1 | Mill Creek Road | 45365 | Sidney | 2007-07-24 17:37:37 |
| 2 | 1 | Main Street | 28681 | Taylorsville | 2007-07-24 17:37:37 |
| 3 | 2 | River Road | 80239 | Denver | 2007-07-24 17:37:37 |
+------------+-----------+-----------------+-------+--------------+---------------------+
3 rows in set (0.00 sec)
<address>
요소의 데이터 중 XML 주석으로되어있는 것은 가져 오지 않습니다. 그러나 address
테이블에는 person_id
열이 있기 때문에 각 <address>
에 대한 부모의 <person>
요소의 person_id
속성의 값은 address
테이블에 가져옵니다.
보안 고려 사항 LOAD DATA
문뿐만 아니라 클라이언트 호스트에서 서버 호스트에 XML 파일의 전송은 MySQL 서버가 시작됩니다. 이론적으로는 LOAD XML
문에서 클라이언트에 의해 지정된 파일이 아니라 서버가 선택한 파일을 전송하도록 클라이언트 프로그램에 지시하는 패치가 적용된 서버를 구축 할 수 있습니다. 그러한 서버는 클라이언트 사용자가 읽기 권한을 가진 클라이언트 호스트의 모든 파일에 액세스 할 수 있습니다.
Web 환경에서는 일반적으로 클라이언트는 Web 서버에서 MySQL에 연결합니다. MySQL 서버에 임의의 명령을 실행할 수있는 사용자는 LOAD XML LOCAL
을 사용하여 Web 서버 프로세스가 읽기 권한을 가진 모든 파일을 읽을 수 있습니다. 이 환경에서는 클라이언트는 MySQL 서버에 Web 서버에 접속하는 사용자에 의해 실행되는 원격 프로그램이 아니라 실제로 Web 서버입니다.
--local-infile=0
또는 --local-infile=OFF
를 사용하여 서버를 시작하여 클라이언트에서 XML 파일로드를 비활성화 할 수 있습니다. 이 옵션은 또한 클라이언트 세션 기간 동안 LOAD XML
을 해제하도록 mysql 클라이언트를 시작하는 경우에도 사용할 수 있습니다.
클라이언트가 서버에서 XML 파일을로드하지 않도록하기 위해 해당 MySQL 사용자 계정에 FILE
권한을 부여하지 않도록하거나 클라이언트 사용자 계정이 이미이 권한이있는 경우 취소하십시오.
FILE
권한을 취소 (또는 처음부터 부여하지 않는) 경우, 그 사용자는 LOAD XML INFILE
문 ( LOAD_FILE()
함수)을 수행 할 수 없게합니다. LOAD XML LOCAL INFILE
의 실행을 방해하지 않습니다. 이 문을 금지하려면 서버 또는 클라이언트를 --local-infile=OFF
로 시작해야합니다.
즉, FILE
권한은 클라이언트가 서버에서 파일을 읽을 수 있는지에만 영향을 미칩니다. 클라이언트가 로컬 파일 시스템에서 파일을 읽을 수 있는지에 상관하지 않습니다.
테이블 잠금을 채용 한 스토리지 엔진 ( MyISAM
등)를 사용하여 파티션 된 테이블의 경우 LOAD XML
은 어떤 파티션 잠금도 정리 할 수 없습니다. 이것은 행 레벨 락을 채용 한 스토리지 엔진 ( InnoDB
등)을 사용하는 테이블에는 적용되지 않습니다. 자세한 내용은 섹션 19.6.4 "파티셔닝 및 잠금" 을 참조하십시오.