2013-01-05 13 views
5

Mam problem z używaniem PDO do wstawiania wielu rekordów do bazy danych. Mogę z powodzeniem dodać pojedynczy rekord, ale jak tylko dodam pętlę foreach, to się nie powiedzie. Po przeczytaniu wielu innych pytań dotyczących SO w tym zakresie, uważam, że muszę "związać" moje zmienne, chociaż jestem całkowicie zdezorientowany z właściwej składni.PHP PDO Insert Using Loop

Oto oryginalna funkcja stworzyłem:

<? function addToDatabase() { 
    //Get All Variables 
    $timestamp = date("Y-m-d H:i:s"); 
    $schoolName = $_SESSION['schoolName']; 
    $schoolStreet = $_SESSION['schoolStreet']; 
    $schoolCity = $_SESSION['schoolCity']; 
    $schoolState = $_SESSION['schoolState']; 
    $schoolZip = $_SESSION['schoolZip']; 
    $schoolContactName = $_SESSION['schoolContactName']; 
    $schoolContactTitle = $_SESSION['schoolContactTitle']; 
    $schoolContactPhone = $_SESSION['schoolContactPhone']; 
    $schoolCsontactEmail = $_SESSION['schoolContactEmail']; 
    $inputMethod = $_SESSION['inputMethod']; 

    $studentDataArray = $_SESSION['studentDataArray']; 

    $studentFirstNameField = $_SESSION['studentFirstNameField']; 
    $studentLastNameField = $_SESSION['studentLastNameField']; 
    $studentStreetField = $_SESSION['studentStreetField']; 
    $studentCityField = $_SESSION['studentCityField']; 
    $studentStateField = $_SESSION['studentStateField']; 
    $studentZipcodeField = $_SESSION['studentZipcodeField']; 
    $studentDOBField = $_SESSION['studentDOBField']; 
    $studentGenderField = $_SESSION['studentGenderField']; 
    $studentGradeField = $_SESSION['studentGradeField']; 

    //Connnect to Database 
    $host = 'myHost'; 
    $un = 'myUsername'; 
    $pw = 'myPassword'; 
    $db_name = 'myTable'; 

    try { 
     $conn = new PDO("mysql:host=$host;dbname=$dbName", $un, $pw); 
     echo 'Connected to database<br>'; 

     $sql = "INSERT INTO studentData (originallyAddedOn, inputMethod, studentFirst, studentLast, studentStreet, studentCity, studentState, studentZip, studentDOB, studentGender, studentGrade, schoolName, schoolStreet, schoolCity, schoolState, schoolZip, schoolContactName, schoolContactTitle, schoolContactEmail, schoolContactPhone) VALUES (:originallyAddedOn, :inputMethod, :studentFirst, :studentLast, :studentStreet, :studentCity, :studentState, :studentZip, :studentDOB, :studentGender, :studentGrade, :schoolName, :schoolStreet, :schoolCity, :schoolState, :schoolZip, :schoolContactName, :schoolContactTitle, :schoolContactEmail, :schoolContactPhone)"; 

     foreach ($studentDataArray as $student){ 
      $q = $conn->prepare($sql); 
      echo $student[$studentFirstNameField]."<br>"; 
      $q->execute(array( ':originallyAddedOn'=>$timestamp, 
          ':inputMethod'=>$inputMethod, 
          ':studentFirst'=>$student[$studentFirstNameField], 
          ':studentLast'=>$student[$studentLastNameField], 
          ':studentStreet'=>$student[$studentStreetField], 
          ':studentCity'=>$student[$studentCityField], 
          ':studentState'=>$student[$studentStateField], 
          ':studentZip'=>$student[$studentZipField], 
          ':studentDOB'=>$student[$studentDOBField], 
          ':studentGender'=>$student[$studentGenderField], 
          ':studentGrade'=>$student[$studentGradeField], 
          ':schoolName'=>$schoolName, 
          ':schoolStreet'=>$schoolStreet, 
          ':schoolCity'=>$schoolCity, 
          ':schoolState'=>$schoolState, 
          ':schoolZip'=>$schoolZip, 
          ':schoolContactName'=>$schoolContactName, 
          ':schoolContactTitle'=>$schoolContactTitle, 
          ':schoolContactEmail'=>$schoolContactEmail, 
          ':schoolContactPhone'=>$schoolContactPhone));   
      } 
      // close the database connection 
      $dbh = null; 
     } 
     catch(PDOException $e) { 
      echo $e->getMessage(); 
      } 
    } 

$studentDataArray wygląda podobnie do tego:

0 => //student 1 
    array 
     [0] => 'Joe' //First 
     [1] => 'Smith' //Last 
     [2] => '101 Main St' //Street 
     [3] => 'Boston' //City 
     [4] => 'MA' //State 
     [5] => '' //Zip 
     [6] => '2000-01-01' //Date of Birth 
     [7] => 'Male' //Gender 
     [8] => '12' //Grade 

1 => //Student 2 
    array 
     [0] => 'Jane' 
     [1] => 'Smith' 
     [2] => '99 Main St' 
     [3] => 'Boston' 
     [4] => 'MA' 
     [5] => '' 
     [6] => '2000-02-02' 
     [7] => 'Female' 
     [8] => '10' 


UPDATE: Dla tych, którzy są zainteresowani, tutaj jest moja ostateczna funkcja po naprawieniu błędów:

<? function addToDatabase ($dataArray) { 

    //Connnect to Database 
    $host = 'myHost'; 
    $un = 'myUsername'; 
    $pw = 'myPassword'; 
    $db_name = 'myTable';  

    try { 
     $conn = new PDO("mysql:host=$host;dbname=$dbName", $un, $pw); 
     echo 'Connected to database<br>'; 

     $sql = "INSERT INTO studentData (originallyAddedOn, inputMethod, studentFirst, studentLast, studentStreet, studentCity, studentState, studentZip, studentDOB, studentGender, studentGrade, schoolName, schoolStreet, schoolCity, schoolState, schoolZip, schoolContactName, schoolContactTitle, schoolContactEmail, schoolContactPhone) VALUES (:originallyAddedOn, :inputMethod, :studentFirst, :studentLast, :studentStreet, :studentCity, :studentState, :studentZip, :studentDOB, :studentGender, :studentGrade, :schoolName, :schoolStreet, :schoolCity, :schoolState, :schoolZip, :schoolContactName, :schoolContactTitle, :schoolContactEmail, :schoolContactPhone)"; 
     $q = $conn->prepare($sql); 

     foreach ($dataArray as $student){ 
      $a = array (':originallyAddedOn'=>$student['timestamp'], 
         ':inputMethod'=>$student['inputMethod'], 
         ':studentFirst'=>$student['studentFirst'], 
         ':studentLast'=>$student['studentLast'], 
         ':studentStreet'=>$student['studentStreet'], 
         ':studentCity'=>$student['studentCity'], 
         ':studentState'=>$student['studentState'], 
         ':studentZip'=>$student['studentZip'], 
         ':studentDOB'=>$student['studentDOB'], 
         ':studentGender'=>$student['studentGender'], 
         ':studentGrade'=>$student['studentGrade'], 
         ':schoolName'=>$student['schoolName'], 
         ':schoolStreet'=>$student['schoolStreet'], 
         ':schoolCity'=>$student['schoolCity'], 
         ':schoolState'=>$student['schoolState'], 
         ':schoolZip'=>$student['schoolZip'], 
         ':schoolContactName'=>$student['schoolContactName'], 
         ':schoolContactTitle'=>$student['schoolContactTitle'], 
         ':schoolContactEmail'=>$student['schoolContactEmail'], 
         ':schoolContactPhone'=>$student['schoolContactPhone']); 

      if ($q->execute($a)) {   
       // Query succeeded. 
       } else { 
        // Query failed. 
        echo $q->errorCode(); 
        } 
      // close the database connection 
      $dbh = null; 
      echo "Insert Complete!"; 
     } 
     } 
     catch(PDOException $e) { 
      echo $e->getMessage(); 
      } 
    } 
+2

proszę przenieść kod, który wstawia tablicę do bazy danych w zależności od jego własne. Na twoje pytanie tutaj nie powinno to odgrywać żadnej roli, z której pochodzi ta tablica (np. To, co robisz tutaj z '$ _SESSION', stoi na drodze do dobrego przykładu). Utworzenie takiej funkcji pomoże również ograniczyć skutki uboczne, które mogą pozostawiać otwarte miejsca na błędy. – hakre

+0

Dzięki @hakre! Okazuje się, że mój kod powinien ... zadziałać. Miałem wiele błędów w moim kodzie, które nie pojawiły się do tej pory. –

Odpowiedz

7

Nie musisz wiązać zmiennych. Zrobiłem to wcześniej z podobnym kodem. Trudno powiedzieć, co jest nie tak. Czy otrzymujesz wyjątek - jeśli tak, to co to jest?

Jedyne co widzę źle jest mieć swój preparat wewnątrz pętli ... powinno być więcej takich jak:

try { 
     $conn = new PDO("mysql:host=$host;dbname=$dbName", $un, $pw); 
     echo 'Connected to database<br>'; 

     $sql = "INSERT INTO studentData (originallyAddedOn, inputMethod, studentFirst, studentLast, studentStreet, studentCity, studentState, studentZip, studentDOB, studentGender, studentGrade, schoolName, schoolStreet, schoolCity, schoolState, schoolZip, schoolContactName, schoolContactTitle, schoolContactEmail, schoolContactPhone) VALUES (:originallyAddedOn, :inputMethod, :studentFirst, :studentLast, :studentStreet, :studentCity, :studentState, :studentZip, :studentDOB, :studentGender, :studentGrade, :schoolName, :schoolStreet, :schoolCity, :schoolState, :schoolZip, :schoolContactName, :schoolContactTitle, :schoolContactEmail, :schoolContactPhone)"; 

     // prepare once... exceute many :-) 
     $q = $conn->prepare($sql); 

     foreach($studentDataArray as $student) { 
      $q->execute($yourDataArray); 
      // do other stuff if needed 

     } 

} catch(PDOException $e) { 
    echo $e->getMessage(); 
} 
+1

Właśnie dodałem przykład ze zmiennym wiązaniem, które * może * (jeśli ktoś lubi) rozwiązać również aliasing. Reszta jest bardzo podobna do twojej, powiedziałbym też, że bardzo ważne jest przygotowanie zapytania tylko raz na początku, ale wykonując wiele razy. http://stackoverflow.com/a/14167897/367456 – hakre

+0

Dzięki @prodigitalson! Po wykonaniu sugestii @hakre przeniesienia aspektu $ _SESSION z tej funkcji, znalazłem wiele błędów, które nie pojawiły się aż do tego ostatniego kroku. –

+0

Czy mógłbyś pokazać przykład dla "$ yourDataArray" –

2

pętli, zrób to (ChNP lub innych bibliotek klienta bazy danych, które obsługują przygotowanych sprawozdań) :

  1. przygotować zapytanie SQL .
  2. powiązać zmienne.
  3. Zapętlić tablicę ze zmiennymi związanymi, wykonaj raz na iterację.

Zysk.

Dla przykładu opartego na PDO na tablicy z danymi do wstawienia do tabeli, która wymaga pojedynczej kolumny o nazwie option.

Pierwsze niektóre dane mają być wprowadzone do bazy danych:

$options = [ 
    ['option' => "Insert Option A " . uniqid()], 
    ['option' => "Insert Option B " . uniqid()], 
    ['option' => "Insert Option C " . uniqid()], 
]; 

gdzieś indziej, załóżmy, że $options mieć tablicę i dbają o interakcji bazy danych. To wymaga połączenia:

$conn = new PDO('mysql:dbname=test;host=localhost', 'testuser', 'test'); 

$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); 

Teraz przygotujemy zapytanie wstawiania. Używając tutaj nazwanych parametrów, jak w pytaniu, na pewno działa to również z parametrami ponumerowanymi:

$stmt = $conn->prepare('INSERT INTO config (`OPTION`) VALUES (:OPTION);'); 

Zmieńmy teraz nazwany parametr na zmienną. Zwróć uwagę, że zmienna jest prefiksowana (tutaj z insert). Jest to właściwie aliasing do klucza w tablicy wejściowej option:

$stmt->bindParam(':OPTION', $insert_option); 

Więc teraz z listy numerowanej powyżej, punkty 1) przygotowanie zapytania SQL INSERT. i 2.) wiążą zmienne. zostało zrobione.

Tylko lewa jest pętla na tablicy $options wstawić wartości:

foreach ($options as $insert) { 
    extract($insert, EXTR_PREFIX_ALL, 'insert'); 
    $stmt->execute(); 
} 

Wykorzystywanie extract pozwala na ustawienie wielu zmiennych naraz na podstawie tablicy wejście w aliasing mody bez większych ceregieli.

Pełne przykład:

$options = [ 
    ['option' => "Insert Option A " . uniqid()], 
    ['option' => "Insert Option B " . uniqid()], 
    ['option' => "Insert Option C " . uniqid()], 
]; 

$conn = new PDO('mysql:dbname=test;host=localhost', 'testuser', 'test'); 

$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); 

# 1. Prepare  
$stmt = $conn->prepare('INSERT INTO config (`OPTION`) VALUES (:OPTION);'); 

# 2. Bind 
$stmt->bindParam(':OPTION', $insert_option); 

# 3. Loop & Execute 
foreach ($options as $insert) { 
    extract($insert, EXTR_PREFIX_ALL, 'insert'); 
    $stmt->execute(); 
} 
+0

Dlaczego miałbyś budować w ten sposób, zamiast tworzyć tylko jedno przygotowane zapytanie? Nie ma potrzeby włączania pętli przy wykonywaniu wstawki PDO. – JM4