2013-06-11 6 views
7

MySQL 데이터베이스에로드해야하는 CSV 데이터가 있습니다. 글쎄요, 아마도 CSV-ish 일 겁니다. (편집 : actually, it looks like the stuff described in RFC 4180)CSV 파일의 LOAD DATA 여기서 doublequote가 이스케이프 문자로 사용되었습니다

각 행은 쉼표로 구분 된 이중 인용 문자열의 목록입니다. 열 값 내에 나타나는 모든 이중 따옴표를 이스케이프하려면 이중 따옴표가 사용됩니다. 역 슬래시는 자체를 나타낼 수 있습니다. 예를 들어

라인 : JSON으로 파싱 경우

"", "\wave\", ""hello,"" said the vicar", "what are ""scare-quotes"" good for?", "I'm reading ""Bossypants""" 

가 있어야한다 :

[ "", "\\wave\\", "\"hello,\" said the vicar", "what are \"scare-quotes\" good for?", "I'm reading \"Bossypants\"" ] 

내가에서 CSV를 읽을 LOAD DATA를 사용하려고 해요,하지만 난 실행 해요 이상한 행동으로. 예를 들어


, 내 입력 파일의 최초의 비 헤더 행 ""에 끝나는 경우 나는 간단한 2 열 테이블을

shell% mysql exampledb -e "describe person" 
+-------+-----------+------+-----+---------+-------+ 
| Field | Type  | Null | Key | Default | Extra | 
+-------+-----------+------+-----+---------+-------+ 
| ID | int(11) | YES |  | NULL |  | 
| UID | char(255) | YES |  | NULL |  | 
+-------+-----------+------+-----+---------+-------+ 
shell% 

이있는 경우 고려 :

shell% cat temp-1.csv 
"ID","UID" 
"9","" 
"0","Steve the Pirate" 
"1","\Alpha" 
"2","Hoban ""Wash"" Washburne" 
"3","Pastor Veal" 
"4","Tucker" 
"10","" 
"5","Simon" 
"6","Sonny" 
"7","Wat\" 

I 헤더가 아닌 모든 줄을로드 할 수 있지만 첫 번째 줄은로드 할 수 있습니다.

mysql> DELETE FROM person; 
Query OK, 0 rows affected (0.00 sec) 

mysql> LOAD DATA 
      LOCAL INFILE 'temp-1.csv' 
      INTO TABLE person 
      FIELDS 
      TERMINATED BY ',' 
      ENCLOSED BY '"' 
      ESCAPED BY '"' 
      LINES 
      TERMINATED BY '\n' 
      IGNORE 1 LINES 
     ; 
Query OK, 9 rows affected (0.00 sec) 
Records: 9 Deleted: 0 Skipped: 0 Warnings: 0 

mysql> SELECT * FROM person; 
+------+------------------------+ 
| ID | UID     | 
+------+------------------------+ 
| 0 | Steve the Pirate  | 
| 10 |      | 
| 1 | \Alpha     | 
| 2 | Hoban "Wash" Washburne | 
| 3 | Pastor Veal   | 
| 4 | Tucker     | 
| 5 | Simon     | 
| 6 | Sonny     | 
| 7 | Wat\     | 
+------+------------------------+ 
9 rows in set (0.00 sec) 

아니면 내가 헤더를 포함한 모든 행을로드 할 수 "" 내 입력 파일 끝의 더 선 경우

mysql> DELETE FROM person; 
Query OK, 9 rows affected (0.00 sec) 

mysql> LOAD DATA 
      LOCAL INFILE 'temp-1.csv' 
      INTO TABLE person 
      FIELDS 
      TERMINATED BY ',' 
      ENCLOSED BY '"' 
      ESCAPED BY '"' 
      LINES 
      TERMINATED BY '\n' 
      IGNORE 0 LINES 
     ; 
Query OK, 11 rows affected, 1 warning (0.01 sec) 
Records: 11 Deleted: 0 Skipped: 0 Warnings: 1 

mysql> show warnings; 
+---------+------+--------------------------------------------------------+ 
| Level | Code | Message            | 
+---------+------+--------------------------------------------------------+ 
| Warning | 1366 | Incorrect integer value: 'ID' for column 'ID' at row 1 | 
+---------+------+--------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> SELECT * FROM person; 
+------+------------------------+ 
| ID | UID     | 
+------+------------------------+ 
| 0 | UID     | 
| 9 |      | 
| 0 | Steve the Pirate  | 
| 10 |      | 
| 1 | \Alpha     | 
| 2 | Hoban "Wash" Washburne | 
| 3 | Pastor Veal   | 
| 4 | Tucker     | 
| 5 | Simon     | 
| 6 | Sonny     | 
| 7 | Wat\     | 
+------+------------------------+ 
11 rows in set (0.00 sec) 

:

mysql> DELETE FROM person; 
Query OK, 11 rows affected (0.00 sec) 

mysql> LOAD DATA 
      LOCAL INFILE 'temp-2.csv' 
      INTO TABLE person 
      FIELDS 
      TERMINATED BY ',' 
      ENCLOSED BY '"' 
      ESCAPED BY '"' 
      LINES 
      TERMINATED BY '\n' 
      IGNORE 1 LINES 
     ; 
Query OK, 0 rows affected (0.00 sec) 
Records: 0 Deleted: 0 Skipped: 0 Warnings: 0 

mysql> SELECT * FROM person; 
Empty set (0.00 sec) 
:

shell% cat temp-2.csv 
"ID","UID" 
"0","Steve the Pirate" 
"1","\Alpha" 
"2","Hoban ""Wash"" Washburne" 
"3","Pastor Veal" 
"4","Tucker" 
"5","Simon" 
"6","Sonny" 
"7","Wat\" 

그때 내가 어떤 라인을로드 할 수 없습니다 중

또는 헤더를 포함하여 모든 행을로드 할 수 있습니다.

mysql> DELETE FROM person; 
Query OK, 0 rows affected (0.00 sec) 

mysql> LOAD DATA 
      LOCAL INFILE 'temp-2.csv' 
      INTO TABLE person 
      FIELDS 
      TERMINATED BY ',' 
      ENCLOSED BY '"' 
      ESCAPED BY '"' 
      LINES 
      TERMINATED BY '\n' 
      IGNORE 0 LINES 
     ; 
Query OK, 9 rows affected, 1 warning (0.03 sec) 
Records: 9 Deleted: 0 Skipped: 0 Warnings: 1 

mysql> show warnings; 
+---------+------+--------------------------------------------------------+ 
| Level | Code | Message            | 
+---------+------+--------------------------------------------------------+ 
| Warning | 1366 | Incorrect integer value: 'ID' for column 'ID' at row 1 | 
+---------+------+--------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> SELECT * FROM person; 
+------+------------------------+ 
| ID | UID     | 
+------+------------------------+ 
| 0 | UID     | 
| 0 | Steve the Pirate  | 
| 1 | \Alpha     | 
| 2 | Hoban "Wash" Washburne | 
| 3 | Pastor Veal   | 
| 4 | Tucker     | 
| 5 | Simon     | 
| 6 | Sonny     | 
| 7 | Wat\     | 
+------+------------------------+ 
9 rows in set (0.00 sec) 

이제 잘못된 방법을 많이 발견 했으므로 LOAD DATA을 사용하여 이러한 파일의 데이터를 데이터베이스로 가져올 수 있습니까? the documentation for LOAD DATA, treating doubled double quotes as a double quote is the default 따르면

답변

15

: 필드는 문자로 둘러싸인 시작하면

, 그 문자의 경우는 시퀀스 종료 필드 또는 행 하였다에만 필드 값 종료로 인식된다. 모호성을 피하기 위해 필드 값 내에서 ENCLOSED BY 문자의 발생은 두 배가되고 문자의 단일 인스턴스로 해석됩니다. 다음과 같이 ENCLOSED BY ' "'예를 들어, 지정, 따옴표 처리됩니다

"The ""BIG"" boss" -> The "BIG" boss 
The "BIG" boss  -> The "BIG" boss 
The ""BIG"" boss -> The ""BIG"" boss 

그래서 ESCAPED BY ''를 사용하여 이스케이프 문자로 \를 해석하지 않도록 설정하기 만하면됩니다.

LOAD DATA 
    LOCAL INFILE 'temp-1.csv' 
    INTO TABLE person 
    FIELDS 
    TERMINATED BY ',' 
    ENCLOSED BY '"' 
    ESCAPED BY '' 
    LINES 
    TERMINATED BY '\n' 
    IGNORE 1 LINES 
; 
+0

+1 귀하의 제안은 한 가지 더 많은 문제를 해결하는 데 도움이되었습니다. 나는 모든 필드를 csv에서 큰 따옴표로 묶었고 필드가 비어 있으면 csv는 단지 빈 따옴표 2 개를 가질 것입니다. "- 이스케이프 문자로 가정하고 데이터 가져 오기 명령이 작동하지 않습니다. ESCAPED BY를 쓰면 일을 끝냈습니다. 감사. – Aakash

+0

나는 이스케이프 문자가 없기 때문에 정확히 rfc 4180 인 데이터를 가지고 있습니다. 필드 옆에 쉼표가 있으면 큰 따옴표로 묶어야합니다. 이 경우'ESCAPED BY '를 사용합니까? – CMCDragonkai