2013-01-05 29 views
5

Tôi gặp sự cố khi sử dụng PDO để chèn nhiều bản ghi vào cơ sở dữ liệu. Tôi có thể thêm thành công một bản ghi, nhưng ngay sau khi tôi thêm vòng lặp foreach, nó không thành công. Sau khi đọc một số câu hỏi SO khác liên quan đến điều này, tôi tin rằng tôi cần phải "ràng buộc" các biến của tôi, mặc dù tôi hoàn toàn nhầm lẫn về cú pháp thích hợp.PHP PDO Chèn Sử dụng Vòng

Đây là chức năng ban đầu tôi đã tạo:

<? 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(); 
      } 
    } 

Các $studentDataArray trông tương tự như sau:

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: Đối với những người quan tâm, đây là chức năng cuối cùng của tôi sau khi tôi sửa lỗi:

<? 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

Hãy di chuyển phần mã mà chèn mảng vào cơ sở dữ liệu vào một chức năng của riêng của nó. Đối với câu hỏi của bạn ở đây nó không nên chơi bất kỳ hình thức vai trò nơi mà mảng đến từ (ví dụ như những gì bạn làm ở đây với '$ _SESSION' đứng chỉ trong cách của một ví dụ tốt). Việc tạo ra một chức năng như vậy cũng sẽ giúp giảm tác dụng phụ mà bạn có thể đã để lại một nơi nào đó mở ra cho các lỗi. – hakre

+0

Cảm ơn @hakre! Hóa ra mã của tôi _should_ đã làm việc. Tôi đã có nhiều lỗi trong mã của tôi mà đã không xuất hiện cho đến bây giờ. –

Trả lời

7

Bạn không cần phải ràng buộc các biến của mình. Tôi đã làm điều này trước với mã tương tự. Thật khó để nói những gì đang xảy ra mặc dù sai. Bạn có ngoại lệ không - nếu có thì nó là gì?

Điều duy nhất tôi thấy sai là bạn phải chuẩn bị của bạn bên trong vòng lặp ... nên được nhiều hơn như:

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

Chỉ cần thêm một ví dụ với biến ràng buộc mà * có thể * (nếu thích) giải quyết bí danh là tốt. Phần còn lại là rất giống với của bạn, tôi cũng sẽ nói, rằng nó là rất quan trọng để chuẩn bị truy vấn chỉ một lần trong đầu nhưng thực hiện nhiều lần. http://stackoverflow.com/a/14167897/367456 – hakre

+0

Cảm ơn @prodigitalson! Sau khi thực hiện đề xuất @hakre về việc di chuyển khía cạnh $ _SESSION ra khỏi hàm, tôi đã tìm thấy một số lỗi không xuất hiện cho đến bước cuối cùng này. –

+0

Bạn có thể hiển thị ví dụ cho "$ yourDataArray" –

2

Đối với các vòng lặp, làm được điều này (PDO hoặc các thư viện cơ sở dữ liệu khách hàng khác có hỗ trợ chuẩn bị phát biểu) :

  1. chuẩn bị truy vấn SQL INSERT.
  2. ràng buộc các biến.
  3. lặp mảng của bạn dựa trên các biến liên kết, thực hiện một lần cho mỗi lần lặp.

Lợi nhuận.

Ví dụ dựa trên PDO trên mảng có dữ liệu để chèn vào một số bảng yêu cầu cột đơn có tên option.

Đầu tiên một số dữ liệu được đưa vào cơ sở dữ liệu:

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

Một nơi nào đó khác, hãy giả sử có được điều đó $options mảng và quan tâm đến sự tương tác cơ sở dữ liệu. Điều này cần có kết nối:

$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); 

Bây giờ hãy chuẩn bị truy vấn chèn. Sử dụng tên thông số ở đây giống như trong câu hỏi, chắc chắn điều này làm việc với các thông số được đánh số, quá:

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

Bây giờ chúng ta hãy liên kết các tham số được đặt tên cho một biến ở đây. Lưu ý rằng biến được đặt trước (ở đây là insert). Đây thực sự là răng cưa với option then chốt trong mảng đầu vào:

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

Vì vậy, bây giờ từ danh sách được đánh số trên, các điểm 1.) chuẩn bị các truy vấn SQL INSERT. và 2.) ràng buộc các biến. đã được thực hiện.

Chỉ trái là vòng lặp qua mảng $options để chèn các giá trị:

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

Tận dụng extract cho phép thiết lập nhiều biến cùng một lúc dựa trên mảng đầu vào theo kiểu răng cưa mà không cần nhiều ado.

Các ví dụ đầy đủ:

$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

Tại sao bạn xây dựng theo cách này thay vì chỉ tạo một truy vấn được chuẩn bị đơn? Không cần lặp lại thao tác chèn PDO. – JM4

Các vấn đề liên quan