Witam wszystkich,
mam problem z importem pliku CSV do bazy danych. Oczywiście zwykłe importowanie działa, ale nie zadowala mnie wynik tego importu.
Załóżmy że mam plik CSV wyglądający tak:
3504,72.00,011179239474,U23947,"nazwa 1"
3506,72.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"
3506,22.00,011179238910,U23891,"nazwa 2"
Jak widać 2 i 4 wiersz jest taki sam, różni się jedynie drugą kolumną. W moim kodzie importuje się jednak tylko jeden wiersz, ten, który jest wyżej. W tym wypadku 4 wiersz jest pomijany. Zwracane jest coś takiego:
3504,72.00,011179239474,U23947,"nazwa 1"
3506,72.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"
Efekt jaki chcę osiągnąć to:
3504,72.00,011179239474,U23947,"nazwa 1"
3506,94.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"
Czyli wartość np. z 2 kolumny się sumowała. 1 kolumna jest unikalna i niepowtarzalna, więc rekordy, które mają tą samą liczbę w kolumnie 1 powinny sumować wynik z kolumny 2. Nie wiem czy jasno wytłumaczyłem.
Do tej pory używałem do importu takiego kodu:
<?php include 'dbConfig.php'; if(http://www.php.net/isset($_POST['importSubmit'])){ $csvMimes = http://www.php.net/array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'); if(!http://www.php.net/empty($_FILES['file']['name']) && http://www.php.net/in_array($_FILES['file']['type'],$csvMimes)){ if(http://www.php.net/is_uploaded_file($_FILES['file']['tmp_name'])){ $csvFile = http://www.php.net/fopen($_FILES['file']['tmp_name'], 'r'); http://www.php.net/fgetcsv($csvFile); while(($line = http://www.php.net/fgetcsv($csvFile)) !== FALSE){ $db->query("INSERT INTO produkty (numer, ilosc, ean, kod1, nazwa) VALUES ('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."','".$line[5]."')"); } http://www.php.net/fclose($csvFile); $qstring = '?status=sukces'; }else{ $qstring = '?status=error'; } }else{ $qstring = '?status=nieprawidlowy_plik'; } } http://www.php.net/header("Location: index.php".$qstring); ?>
https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
Dzięki za nakierowanie.
Poczytałem trochę o tym i poprawiłem kod, który jednak nie działa. Efekt jest taki sam.
<?php include 'dbConfig.php'; if(http://www.php.net/isset($_POST['importSubmit'])){ $csvMimes = http://www.php.net/array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'); if(!http://www.php.net/empty($_FILES['file']['name']) && http://www.php.net/in_array($_FILES['file']['type'],$csvMimes)){ if(http://www.php.net/is_uploaded_file($_FILES['file']['tmp_name'])){ $csvFile = http://www.php.net/fopen($_FILES['file']['tmp_name'], 'r'); http://www.php.net/fgetcsv($csvFile); while(($line = http://www.php.net/fgetcsv($csvFile)) !== FALSE){ $db->query("INSERT INTO produkty (numer, ilosc, ean, kod1, nazwa) VALUES ('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."','".$line[5]."') ON DUPLICATE KEY UPDATE ilosc = VALUES(ilosc)" "); } fclose($csvFile); $qstring = '?status=sukces'; }else{ $qstring = '?status=error'; } }else{ $qstring = '?status=nieprawidlowy_plik'; } } header("Location: index.php".$qstring); ?>
Tak sie w mysql dodaje wartosci:
pole = pole + 5
gdzie 5 to wartosc 5 ktora chcesz dodac do pola pole.
Podobnie sie sumuje w kazdym innym czy to jezyku czy to bazie danych.
Zas
pole = 5
zawsze nadpisuje wartosc pola pole wartoscia 5. To jest dosc logiczne i dziala tak samo rowniez wszedzie
Tak faktycznie, głupio trochę to napisałem. W tej chwili ostatnią wartość dodaje z listy. Tylko jak zrobić sumowanie wszystkich liczb z kolumny dla jednego KEYa? Próbowałem z SUM lecz nie przechodziło
No przeciez w poprzednim poscie ci napisalem jak sie SUMUJE. Ty zas masz tam ciagle nadpisywanie temu ci wpisuje ostatnia wartosc. Zmien na to co ci napisalem.
No tak, tylko że ja nie wiem jaka tam będzie wartość dodana i nie mogę zrobić sobie +1, +2 czy +10. Może być 20 a może być i 30. Plik CSV, który importuje może mieć 3 wartości z jednym kluczem.
Mogę mieć CSV który wygląda tak:
3504,72.00,011179239474,U23947,"nazwa 1"
3506,72.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"
3506,22.00,011179238910,U23891,"nazwa 2"
i wynik dla 3506 musi być 94 (dla 2 kolumny), a inny CSV może mieć
3504,72.00,011179239474,U23947,"nazwa 1"
3506,72.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"
3506,22.00,011179238910,U23891,"nazwa 2"
3506,22.00,011179238910,U23891,"nazwa 2"
i wtedy wynik musi mieć 116
ON DUPLICATE KEY UPDATE ilosc = ilosc + VALUES(ilosc)
a dla pewności
ON DUPLICATE KEY UPDATE ilosc = Coalesce(ilosc, 0) + VALUES(Coalesce(ilosc,0))
u mnie zadziałało to:
ON DUPLICATE KEY UPDATE ilosc = ilosc+$line[1]
z VALUES i z Coalesce() nic się nie dzieje
Pojawił się przy tym kolejny problem. Problemem jest jeśli plik CSV jest oddzielany średnikiem ; a nie przecinkiem.
Zmieniając fgetcsv($csvFile) na fgetcsv($csvFile, 0, ';') aby rozdzielało po średnikach, wali się wszystko. Nie wczytuje w ogóle do bazy nic.
Usuwając ON DUPLICATE KEY UPDATE ładuje się plik ze średnikami. Wygląda jakby ON DUPLICATE KEY UPDATE kolidował ze średnikami ... możliwe?
Nie. Wyświetl sobie wygenerowane zapytanie to będziesz wiedział dlaczego się sypie.
Ok, udało się. Dzięki wszystkim za pomoc.
Końcowo kod wygląda tak:
<?php include 'dbConfig.php'; if(http://www.php.net/isset($_POST['importSubmit'])){ $csvMimes = http://www.php.net/array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'); if(!http://www.php.net/empty($_FILES['file']['name']) && http://www.php.net/in_array($_FILES['file']['type'],$csvMimes)){ if(http://www.php.net/is_uploaded_file($_FILES['file']['tmp_name'])){ $csvFile = http://www.php.net/fopen($_FILES['file']['tmp_name'], 'r'); http://www.php.net/fgetcsv($csvFile); while(($line = http://www.php.net/fgetcsv($csvFile, 0, ';')) !== FALSE){ $db->query("INSERT INTO produkty (numer, ilosc, ean, kod1, nazwa) VALUES ('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."','".$line[5]."') ON DUPLICATE KEY UPDATE ilosc = ilosc+'".$line[1]."' "); } http://www.php.net/fclose($csvFile); $qstring = '?status=sukces'; }else{ $qstring = '?status=error'; } }else{ $qstring = '?status=nieprawidlowy_plik'; } } http://www.php.net/header("Location: index.php".$qstring); ?>
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)