2014-02-19 3 views
0

데이터베이스에 csv를 삽입하는 데 문제가 있습니다. 테이블의 테이블 구조는 여기CSV 콘텐츠를 mysql 데이터베이스에 저장하십시오.

gender,age,name,location 
male,21,jayvz,spl 
female,21,jacyn,srl 

과 : 여기 내 CSV 콘텐츠 샘플의

  • 이 contact_id ID (자동 증가)
  • 라벨

내가해야 할 일은 CSV에서 그 데이터에 데이터를 삽입하는 것입니다. 이 같은 BLE :
예상 출력 :

id | contact_id | label | value 
1 |  1  | gender | male 
2 |  1  | age  | 21 
3 |  1  | name  | jayvz 
4 |  1  | location | spl 
5 |  2  | gender | female 
6 |  2  | age  | 21 
7 |  2  | name  | jacyn 
8 |  2  | location | srl 

(예상 출력 죄송합니다)

어떤 아이디어? 또는 심지어 이것이 가능한가?

CODE :

$headers = exec("head -n 1 {$paramfile}"); 
$param_names = array_filter(explode(",", $headers)); 
$param_count = count($param_names); 

$contact_count = count($contacts); 

$contactsfile = getcwd()."/uploads/".date('ymdhis').".cntctid"; 
$row = ''; 
$str_csv = array(); 

$tmp_handler = fopen($datafile, 'r'); 
$param_value = ''; 

while(($upload_str = fgets($tmp_handler, 4096)) !== FALSE){ 
    $param_value = explode(",", $upload_str); 
    array_shift($param_value); // msisdn bb 
    $str_line = implode(",", $param_value); 
    //$age = array_shift($param_value); 

    //$row.= implode(",", $param_value); 
    //for($x = 0; $x < count($param_value); ++$x){ 
    // $row.= $param_value[$x].","; 
    //} 

    $str_csv[] = str_getcsv($str_line, ","); 
} 
for($a = 0; $a < $param_count; ++$a){ 
for($i = 0; $i < $contact_count; ++$i){ 
$row = $contacts[$i].",".$param_names[$a].",'<the values should be here>'"; 
exec("echo '".$row."' >> ".$contactsfile); 
} 
} 

$load_query = "LOAD DATA LOCAL INFILE '{$contactsfile}' INTO TABLE {$this->contact_details} "; 
$load_query .= "FIELDS TERMINATED BY ',' LINES TERMINATED BY '\\n' "; 
$load_query .= "(contact_id, label_name, label_value)"; 

$this->db->query($load_query); 

return $this->db->affected_rows() > 0; 
+0

코드를 표시하십시오. –

+0

가능한 복제본 [어떻게 CSV에서 MySQL로 데이터를 가져올 수 있습니까?] (http://stackoverflow.com/questions/9555370/how-i-can-import-data) -from-csv-to-mysql) – randak

+0

거의 모든 것이 가능합니다. 지금까지 코드를 게시하십시오. –

답변

2

이 시도 :

$row = 1; 
$labels = array(); 
if (($handle = fopen("your.csv", "r")) !== FALSE) { 
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 
     if($row==1){ 
      $labels = $data; 
     } else { 
      foreach ($data as $key=>$value) { 
       $query = "insert into table values (null,$row,'{$labels[$key]}','$value')"; 
       $this->db->query($query) 
      } 
     } 
     $row++; 
    } 
    fclose($handle); 
} 
+0

각 줄마다 하나의 인서트가 거대한 CSV 파일에도 적용된다. CSV 데이터가 항상 메모리에 들어가기에 충분히 작 으면 값 배열을 설정하고 해당 루프 다음에 한 번 삽입합니다. – feeela

+0

나는 csv 파일을 위해 아주 많은 양의 데이터를 사용할 것입니다 (예 : 1m 라인 이상 500k까지) –

+0

감사합니다. @HarryFink. 그러나 내 메모리를 소모하지 않고 알고리즘을 실행해야합니다. –

1

가 왜 당신을 위해 그것을 구문 분석 PHP를 사용합니까? 더 많은 통제, 덜 걱정 IMO.

이렇게하려면 줄로 나눈 다음 줄을 필드로 나눕니다. 다음은 문자열 변수에서 사용할 수있는 CSV를하고 있다고 가정 CSV는

$csv 

$lines = explode(PHP_EOL, $csv); 

$load_query = "INSERT INTO table_name (contact, label, value) VALUES "; 

for($i = 1 ; $i < count($lines) ; $i++){ 
    // Split the line into fields 
    $fields = $explode(",", $lines[$i]); 
    // Concatenate the insert values 
    $load_query .= "({$field[0]},{$field[1]},{$field[2]})"; 
    // If there are more lines add a comma 
    if($i < (count($lines)-1)){ 
     $load_query .= ","; 
    } 
} 
// Run the query and return 
$this->db->query($load_query); 
return $this->db->affected_rows() > 0; 

이 필드 (때문에 PHP_EOL 상수의 내 사용) 당신이 그것을 구문 분석하려는 동일한 시스템에 생성 된 것을 정말로 소독되거나 뭔가 있어야합니다. 이 문제가 해결

+0

감사합니다. h.caotes 님의 아이디어 –

0

, 나는, 이름, 1, 위치, SPL 2, 나이, 21 2 jayvz, 21 1이 형식

1, 시대에 csv 파일에 데이터를 작성 이름, jacyn 2, 위치, SRL

는 내가 소모에서 메모리를 방지하기 위해 MySQL의의 부하 지역 INFILE 쿼리를 사용 매우 큰 파일 나는 bash는 스크립트의 '분할'

를 사용 가능한 여러 개의 파일로 나누어

감사합니다. 아이디어. =)

관련 문제