Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]PDO - Dodanie wielu wierszy w jednym zapytaniu
@rtur
post 11.04.2015, 09:28:17
Post #1





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

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


Mam taką tablice:
  1. $tablica = array(
  2. 0=> array (
  3. 'artist'=> 'Opus',
  4. 'songtitle'=> 'Life Is Life',
  5. ),
  6. 1=> array (
  7. 'artist'=> 'Smookie',
  8. 'title'=> 'Needles And Pins',
  9. ),
  10. 2=> array (
  11. 'artist'=>'George Harrison',
  12. 'title'=>'Got My Mind Set On You',
  13. ),
  14. 3=> array (
  15. 'artist'=> 'Smookie',
  16. 'title'=> 'I`ll Mett You At Midnight',
  17. ),
  18. )

Chciałbym dodać dane z tej tablicy do tabeli w bazie danych jednym zapytaniem insert za pomocą PDO
W przypadku jednego rekordu zrobiłbym tak:
  1. $stmt = $pdo -> prepare('INSERT INTO `songs` (`artist`, `title`) VALUES(:artysta,:tytul)');
  2. $stmt -> bindValue(':artysta', $artysta, PDO::PARAM_STR);
  3. $stmt -> bindValue(':tytul', $tytul, PDO::PARAM_STR);
  4. $exec = $stmt -> execute();

Jak wygląda składnia zapytania insert dla wielu rekordów z bindowaniem danych z tablicy w PDO?


--------------------
Artur
Go to the top of the page
+Quote Post
viking
post 11.04.2015, 09:42:47
Post #2





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

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


Jeżeli masz przygotowane zapytanie (prepare) możesz je wykonywać dowolną ilość razy.
http://php.net/manual/en/pdo.prepare.php (przykłady) Execute przyjmuje tablicę danych.


--------------------
Go to the top of the page
+Quote Post
@rtur
post 11.04.2015, 21:54:27
Post #3





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

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


hmm coś takiego?

  1. $artysta=array();
  2. $tytul=array();
  3. foreach ($tablica as $tab){
  4. $artysta[] .= $tab['artist'];
  5. $tytul[] .= $tab['title'];
  6. }
  7.  
  8. $stmt = $pdo -> prepare('INSERT INTO `songs` (`artist`, `title`) VALUES(:artysta,:tytul)');
  9. $stmt -> bindValue(':artysta', $artysta, PDO::PARAM_STR);
  10. $stmt -> bindValue(':tytul', $tytul, PDO::PARAM_STR);
  11. $exec = $stmt -> execute();


Ten post edytował @rtur 11.04.2015, 21:57:40


--------------------
Artur
Go to the top of the page
+Quote Post
viking
post 12.04.2015, 06:08:49
Post #4





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

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


A czy coś takiego jest w przykładach? Parametry muszą się zgadzać też czyli nie raz songtitle, innym razem title.

  1. try {
  2. $dbh = new PDO('pgsql:host=localhost;port=5432;dbname=db;user=user;password=pass');
  3. $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  4. $dbh->exec("SET NAMES 'UTF8';");
  5.  
  6. $tablica = array(
  7. 0 => array(
  8. 'artist' => 'Opus',
  9. 'title' => 'Life Is Life',
  10. ),
  11. 1 => array(
  12. 'artist' => 'Smookie',
  13. 'title' => 'Needles And Pins',
  14. ),
  15. 2 => array(
  16. 'artist' => 'George Harrison',
  17. 'title' => 'Got My Mind Set On You',
  18. ),
  19. 3 => array(
  20. 'artist' => 'Smookie',
  21. 'title' => 'I`ll Mett You At Midnight',
  22. ),
  23. );
  24.  
  25. $stmt = $dbh->prepare('INSERT INTO song (artist, songtitle) VALUES(:artist,:title)');
  26.  
  27. foreach ($tablica as $value) {
  28. $exec = $stmt->execute($value);
  29. }
  30. } catch (PDOException $e) {
  31. echo 'Klasa PDO zwróciła wyjątek: ' . $e->getMessage();
  32. }


http://wwwgo.pl/article/10/php_data_object...luge_baz_danych


--------------------
Go to the top of the page
+Quote Post
@rtur
post 12.04.2015, 07:58:48
Post #5





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

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


Dzięki, oczywiście będzie title w parametrach, moja pomyłka pisarska.

W wyniku tego execute() x4 (tyle jest elementów w tablicy) wykona się 4x zapytanie
  1. INSERT INTO song (artist, songtitle) VALUES(:artist,:title)
tylko za każdym razem z innymi parametrami, czyli mamy 4 zapytania do bazy?

Przy zwykłym mysql_query jest coś takiego
  1. INSERT INTO song (artist, songtitle) VALUES ('Opus','Life Is Life'),('Smookie','Needles And Pins'),('George Harrison','Got My Mind Set On You'),('Smookie','I`ll Mett You At Midnight')
i tu mam jedno zapytanie do bazy.

Przepraszam, do tej pory używałem głównie mysql_ a teraz dopiero zaczynam swoją przygodę z PDO


--------------------
Artur
Go to the top of the page
+Quote Post
Turson
post 12.04.2015, 11:55:23
Post #6





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

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


http://stackoverflow.com/questions/1176352...in-single-query
Go to the top of the page
+Quote Post
@rtur
post 13.04.2015, 21:45:16
Post #7





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

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


Dzięki, czy w PDO moje zapytanie może mieć taką konstrukcję?
  1. $sth = $dbh->prepare('INSERT INTO song (artist, title) VALUES(:artysta1,:tytul1),(:artysta2,:tytul2), ... (:artysta10,:tytul10)');
  2. $sth->bindValue(':artysta1',$artysta[1]);
  3. $sth->bindValue(':tytul1',$tytul[1]);
  4. $sth->bindValue(':artysta2',$artysta[2]);
  5. $sth->bindValue(':tytul2',$tytul[2]);
  6. ...
  7. $sth->bindValue(':artysta10',$artysta[10]);
  8. $sth->bindValue(':tytul10',$tytul[10]);
  9. $sth->execute();


Ten post edytował @rtur 13.04.2015, 21:50:27


--------------------
Artur
Go to the top of the page
+Quote Post
Turson
post 13.04.2015, 21:47:48
Post #8





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

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


Może. Kod można uprościć pętlą
Go to the top of the page
+Quote Post
@rtur
post 13.04.2015, 21:54:19
Post #9





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

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


Oczywiście zrobię go pętlą for, chodziło mi tylko o konstrukcję zapytania. Dzięki za pomoc smile.gif


--------------------
Artur
Go to the top of the page
+Quote Post
viking
post 14.04.2015, 07:54:18
Post #10





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

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


Jeżeli naprawdę chcesz zyskać na wydajności to https://dev.mysql.com/doc/refman/5.6/en/load-data.html
Dopóki nie robisz tysięcy rekordów nie warto sobie głowy zawracać. Zwłaszcza że te dane nie wyglądają na zmienne.


--------------------
Go to the top of the page
+Quote Post
@rtur
post 25.04.2015, 16:46:39
Post #11





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

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


Nie wiem czy jest sens to będzie co 20 minut 20 rekordów próbowało wrzucić... to chyba nie dużo...

Korzystam z tej klasy https://github.com/indieteq/PHP-MySQL-PDO-Database-Class i o ile udało mi się zrobić pętlę Values (:artysta1,:tytul1),....(:artysta20,:tytul20) do zapytania insert dla wielu to nie mogę sobie podpięciem parametrów...
  1. $i=0;
  2. $numItems=20;
  3. foreach($data as $d){
  4. if($i === $numItems) {
  5. $val .= '(:artysta'.$i.',:tytul'.$i.')';
  6. }
  7. else{
  8. $val .= '(:artysta'.$i.',:tytul'.$i.'), ';
  9. }
  10. }
  11. $sqlQuery = 'INSERT INTO song (artist,title) VALUES '.$val;
  12. // Przy pojedynczym rekordzie dane dodałbym tak;
  13. $db->query($sqlQuery,array('artysta1'=>$dane[0][1],'tytul1'=>$dane[0][2]));

W jaki sposób do zmiennej $tablicaDlaWieluParametrow przypisać coś takiego:
  1. $tablicaDlaWieluParametrow = array('artysta1'=>$dane[0][1],'tytul1'=>$dane[0][2],....'artysta20'=>$dane[19][1],'tytul20'=>$dane[19][2]);

aby zadziałało tak:
  1. $db->query($sqlQuery,$tablicaDlaWieluParametrow);

domyślam się że pętlą ale nie chce mi wyjść coś co zadziała jako drugi parametr w funkcji $db->query();

Ten post edytował @rtur 25.04.2015, 16:50:44


--------------------
Artur
Go to the top of the page
+Quote Post
viking
post 25.04.2015, 16:51:39
Post #12





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

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


Skoro jest to 20 rekordów co 20 minut to nie ma sensu nawet nad tym myśleć. Dla bazy to nic. Gdybyś tam miliony wkładał mogła by coś taka optymalizacja przynieść.


--------------------
Go to the top of the page
+Quote Post
@rtur
post 25.04.2015, 17:09:50
Post #13





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

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


no tak w sumie masz rację, teraz nie będą to miliony rekordów ale nie wykluczam że w niedalekiej przyszłości może być 20, 50 lub więcej razy 20 rekordów co 20 minut, nie są to jedyne rekordy jakie będą się dodawały w tym skrypcie, dlatego zawczasu chcę myśleć o optymalizacji zapytań, i np. co się da wrzucić jednym zapytaniem...


--------------------
Artur
Go to the top of the page
+Quote Post
viking
post 25.04.2015, 18:51:12
Post #14





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

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


Poczytaj https://dev.mysql.com/doc/refman/5.0/en/insert-speed.html
Masz kilka możliwości przyśpeiszenia choćby INSERT DELAYED. Pamiętaj o wyłączeniu autocommit czy jak to się zwało w mysql. I odpowiedź Turson pokazała jak zrobić w jednym wywyołaniu.


--------------------
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: 22.06.2025 - 15:32