Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]odczyt danych z pliku txt
Forum PHP.pl > Forum > Przedszkole
Maciek1705
Witam serdecznie bardzo bym Was drodzy forumowicze prosił o pomoc gdyż nie wiem czy dobrze coś robię. Mianowicie chcę zrobić prosty program co po wybraniu pliku txt odczyta jego zawartość a później zawartość tą wstawi do bazy. Jeśli np wiersz o takim identyfikatorze by już istniał to żeby go nadpisał z update owałbiggrin.gif
plik txt wygląda tak
  1. id nazwa faktura data1 data2 data3 kwota
  2. 1 mmm 234 11-11-2010 12-12-2010 01-01-2011 100
  3. 2 nnn 235 10-10-2010 11-11-2010 12-12-2010 200

dane w pliku są rozdzielone znakami tabulacji.

a tak wygląda kod programu
  1. <?php
  2. $dane = file("nazwa_pliku.txt");
  3. if ($dane === false) {
  4. echo "Error - nie można odnaleść pliku";
  5. }
  6. else {
  7. for($i=0; $i<count($dane); $i++) {
  8. $dane[$i] = explode(" ", $dane[$i]);
  9.  
  10. $query = "insert into tabelka values ($dane[$i][0], $dane[$i][1], $dane[$i][2], $dane[$i][3], $dane[$i][4], $dane[$i][5], $dane[$i][6])";
  11. mysql_query($query)
  12. or die ("Wystąpiły problemy przy zapisywaniu danych");
  13. }
  14. }
  15. ?>

nie wiem czy dobrze to zrobiłem jak na stan obecny, nie wiem też także jak rozwiązać kwestie sprawdzania czy wiersz o podanym id istnieje i czy ma zostać nadpisany. Proszę o pomoc i wyrozumiałość biggrin.gif
bastard13
Osobiście to bym zamienił ten separator na jakiś znak np. ';' (średnik),a jak już tab to zapisany w ten sposób '\t', po prostu nie mam do niego zaufania:) i nie jestem pewien, czy taka forma będzie poprawna na każdym systemie.
Co do sprawdzania czy istnieje, to:
  1. $qry='select count(*) from tabelka where id='.$dane[$i][0];

jeżeli zapytanie zwróci 1 to update, w innym wypadku dodaj.
I jeszcze te zmienne ($dane[$i][0]) wrzuciłbym w klamerki: {$dane[$i][0]}, bo w innym wypadku ci ich nie odczyta.
Maciek1705
Aha dzięki wielkie, a mam pytanko jeszcze bo nie mam na razie jak sprawdzić czy to działa ale chodzi mi o to czy nie potrzeba jakiegoś wyrażenia regularnego żeby dzielić poszczególny wiersz na poszczególne części no bo nie mam możliwości zmienienia pliku txt żeby był rozdzielony średnikami niestety jest jak jest i rozdzielony jest tabulatorami chodzi mi jedynie o to czy to co mam zaprezentowane niżej będzie odczytywać plik txt i wszystkie dane do ostatniego wiersza będzie dodawał do tabeli no chyba że już jaki wiersz jest to go zaktualizuje. Mówiąc krócej weźmie wiersz rozdzieli na składowe bez tabulacji i te składowe wstawiał do bazy i tak do ostatniego wiersza. Ale namotałem heh:D a oto wynik końcowy programu:
  1. $dane = file("nazwa_pliku.txt");
  2. if ($dane === false) {
  3. echo "Error - nie można odnaleść pliku";
  4. }
  5. else {
  6. $connection = @mysql_connect('localhost', 'uzytkownik', 'haslo')
  7. or die('Brak połączenia z serwerem. Błąd: '.mysql_error());
  8.  
  9. $db = @mysql_select_db('baza', $connection)
  10. or die('Nie można połączyć się z bazą danych. Błąd: '.mysql_error());
  11.  
  12. for($i=0; $i<count($dane); $i++) {
  13. $dane[$i] = explode('\t', $dane[$i]);
  14.  
  15. $qry_check = 'select count(*) from tabelka where id='.$dane[$i][0];
  16.  
  17. if(mysql_query($qry_check) == 1) {
  18. $qry_update = 'UPDATE tabelka SET pole1='.$dane[$i][1].', pole2='.$dane[$i][2].', pole3='.$dane[$i][3].', pole4='.$dane[$i][4].', pole5='.$dane[$i][5].', pole6='.$dane[$i][6].' WHERE id='.$dane[$i][0];
  19. mysql_query($qry_update)
  20. or die ("Wystąpiły problemy przy aktualizacji danych");
  21. }
  22. else {
  23. $qry_insert = 'INSERT INTO tabelka VALUES ('.$dane[$i][0].', '.$dane[$i][1].', '.$dane[$i][2].', '.$dane[$i][3].', '.$dane[$i][4].', '.$dane[$i][5].', '.$dane[$i][6].')';
  24. mysql_query($qry_insert)
  25. or die ('Wystąpiły problemy przy zapisywaniu danych');
  26. }
  27. }
  28. mysql_close($connection);
  29. }
skarabe.pl
Ten fragment nie zadziała:
  1. if(mysql_query($qry_check) == 1) { /* ... */ }

brakuje mysql_fetch_row() (lub assoc()).

Ten zresztą też:
  1. $dane[$i] = explode('\t', $dane[$i]);

Musisz zamienić cudzysłowy wokół "\t" na podwójne. Samo eksplodowanie jest prawidłowe (nie musisz używać wyrażeń regularnych, o ile jesteś na 100% pewien, że zawsze między kolejnymi kolumnami będzie dokładnie jedna tabulacja).

Moim ulubionym, starym sposobem na zrobienie UPDATE jeśli wiersz już istnieje było (pseudokod):
INSERT IGNORE INTO `...` VALUES (...)
if (mysql_affected_rows() === 0) {
UPDATE `...` SET ... WHERE ...
}

IGNORE jest konieczne, inaczej MySQL zwróci ostrzeżenie.
Maciek1705
ok dziękuję za wskazówki cudzysłów poprawiony, czyli według Twojej sprawdzonej metody rozumiem że zawartość pętli for wyglądała by tak:
  1. $dane[$i] = explode("\t", $dane[$i]);
  2.  
  3. $qry_insert = 'INSERT IGNORE INTO tabelka VALUES ('.$dane[$i][0].', '.$dane[$i][1].', '.$dane[$i][2].', '.$dane[$i][3].', '.$dane[$i][4].', '.$dane[$i][5].', '.$dane[$i][6].')';
  4. mysql_query($qry_insert)
  5. or die ('Wystąpiły problemy przy zapisywaniu danych');
  6. if (mysql_affected_rows() === 0) {
  7. $qry_update = 'UPDATE tabelka SET pole1='.$dane[$i][1].', pole2='.$dane[$i][2].', pole3='.$dane[$i][3].', pole4='.$dane[$i][4].', pole5='.$dane[$i][5].', pole6='.$dane[$i][6].' WHERE id='.$dane[$i][0];
  8. mysql_query($qry_update)
  9. or die ("Wystąpiły problemy przy aktualizacji danych");
  10. }


a według mojego sposobu to w sumie nie wiem jak użyć tej funkcji mysql_fetch_row() bo sprawdzałem w manualu i jest napisane że pobiera jeden wiersz z tabeli a w sumie mi chodzi o te że ma sprawdzić czy wiersz o danym od już istnieje jeśli tak to id zostaje bez zmian aktualizuje się jedynie zawartość. MySQL dopiero poznaje stąd brak wiedzy na temat zastosowania praktycznego.
skarabe.pl
Cytat(Maciek1705 @ 29.07.2010, 23:31:13 ) *
ok dziękuję za wskazówki cudzysłów poprawiony, czyli według Twojej sprawdzonej metody rozumiem że zawartość pętli for wyglądała by tak:
  1. /* ... */

Tak
Cytat(Maciek1705 @ 29.07.2010, 23:31:13 ) *
a według mojego sposobu to w sumie nie wiem jak użyć tej funkcji mysql_fetch_row() bo sprawdzałem w manualu i jest napisane że pobiera jeden wiersz z tabeli a w sumie mi chodzi o te że ma sprawdzić czy wiersz o danym od już istnieje jeśli tak to id zostaje bez zmian aktualizuje się jedynie zawartość. MySQL dopiero poznaje stąd brak wiedzy na temat zastosowania praktycznego.

Np. tak (funkcja narzędziowa dodana dla wygody :))
  1. function array_first($tab)
  2. {
  3. return isset($tab[0]) ? $tab[0] : false;
  4. }
  5.  
  6. /* ... */
  7.  
  8. /*
  9.   Zamiast: if (mysql_query($qry_check) == 1) {
  10. */
  11. if (array_first(mysql_fetch_row(mysql_query($qry_check))) == 1) {

array_first() zwraca pierwszy element wektora (lub false), mysql_fetch_row() zwraca wektor, w którym kolejne wartości to kolejne kolumny wyciągnięte z ostatniego zapytania (mysql_query()) - czyli, w tym wypadku, pierwszą kolumną będzie count(*) - to, o co nam chodzi.
phpion
Cytat(skarabe.pl @ 30.07.2010, 08:43:03 ) *
Np. tak (funkcja narzędziowa dodana dla wygody smile.gif)
  1. function array_first($tab)
  2. {
  3. return isset($tab[0]) ? $tab[0] : false;
  4. }
  5.  
  6. /* ... */
  7.  
  8. /*
  9.   Zamiast: if (mysql_query($qry_check) == 1) {
  10. */
  11. if (array_first(mysql_fetch_row(mysql_query($qry_check))) == 1) {

array_first() zwraca pierwszy element wektora (lub false), mysql_fetch_row() zwraca wektor, w którym kolejne wartości to kolejne kolumny wyciągnięte z ostatniego zapytania (mysql_query()) - czyli, w tym wypadku, pierwszą kolumną będzie count(*) - to, o co nam chodzi.

Od tego jest mysql_result.
skarabe.pl
Cytat(phpion @ 30.07.2010, 08:45:27 ) *
Od tego jest mysql_result.

Aha, jakoś nigdy tego nie używałem. W takim razie będzie:
  1. if (mysql_result(mysql_query($qry_check), 0, 0) == 1) {
Maciek1705
dziękuje za pomoc wszystko poprawione według wskazówek. Wszyscy dostaną po "Pomógł" biggrin.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.