Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL][PHP]odczyt danych z pliku txt, z txt do mysql
Maciek1705
post 29.07.2010, 15:38:43
Post #1





Grupa: Zarejestrowani
Postów: 157
Pomógł: 3
Dołączył: 15.06.2009

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
bastard13
post 29.07.2010, 15:53:39
Post #2





Grupa: Zarejestrowani
Postów: 664
Pomógł: 169
Dołączył: 8.01.2010
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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.

Ten post edytował bastard13 29.07.2010, 16:00:47


--------------------
Go to the top of the page
+Quote Post
Maciek1705
post 29.07.2010, 19:27:05
Post #3





Grupa: Zarejestrowani
Postów: 157
Pomógł: 3
Dołączył: 15.06.2009

Ostrzeżenie: (0%)
-----


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. }
Go to the top of the page
+Quote Post
skarabe.pl
post 29.07.2010, 20:45:11
Post #4





Grupa: Zarejestrowani
Postów: 142
Pomógł: 49
Dołączył: 29.07.2010

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
Maciek1705
post 29.07.2010, 22:31:13
Post #5





Grupa: Zarejestrowani
Postów: 157
Pomógł: 3
Dołączył: 15.06.2009

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
skarabe.pl
post 30.07.2010, 07:43:03
Post #6





Grupa: Zarejestrowani
Postów: 142
Pomógł: 49
Dołączył: 29.07.2010

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
phpion
post 30.07.2010, 07:45:27
Post #7





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




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.
Go to the top of the page
+Quote Post
skarabe.pl
post 30.07.2010, 07:55:53
Post #8





Grupa: Zarejestrowani
Postów: 142
Pomógł: 49
Dołączył: 29.07.2010

Ostrzeżenie: (0%)
-----


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) {
Go to the top of the page
+Quote Post
Maciek1705
post 30.07.2010, 09:37:26
Post #9





Grupa: Zarejestrowani
Postów: 157
Pomógł: 3
Dołączył: 15.06.2009

Ostrzeżenie: (0%)
-----


dziękuje za pomoc wszystko poprawione według wskazówek. Wszyscy dostaną po "Pomógł" biggrin.gif
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 6.07.2025 - 21:04