2013-01-05 25 views
5

PDOを使用して複数のレコードをデータベースに挿入する際に問題があります。私は正常に単一のレコードを追加することができますが、foreachループを追加するとすぐに失敗します。これに関する多くの他のSOの質問を読んだ後、私は正しい構文に完全に混乱していますが、変数を "バインド"する必要があると思います。ここでPHP PDOループを使用して挿入

は、私が作成した元の関数である:

<? 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は次のようになります。

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:興味のあるものについては、ここでは私の最後の関数でありますエラーを修正した後:

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

それ自身の関数にデータベースに配列を挿入するコードを移動してください。あなたの質問のために、ここではその配列がどこから来るのかを示す役割を果たしてはいけません(例えば、 '$ _SESSION'を使ってここでやることは良い例のようになります)。このような関数を作成すると、エラーのためにいくつかの場所を開いたままにしておいた副作用を減らすのにも役立ちます。 – hakre

+0

ありがとう@hakre!私のコードはうまくいきました。今まで私のコードには複数のエラーが発生していませんでした。 –

答えて

7

変数をバインドする必要はありません。これまでも同様のコードでこれを行っています。しかし、何がうまくいかないのかは言い難い。あなたは例外を受け取りますか?もしそうなら、それは何ですか?

私が間違っ見る唯一のものは、あなたがループ内で、あなたの準備を持っている...もっとようにする必要があります:、

ループの場合
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

変数バインディングを使用してエイリアシングを解決できる*(*が好きな場合)という例を追加しました。残りはあなたのものと非常によく似ていますが、私は、最初にクエリを1回だけ準備し、複数回実行することは非常に重要であるとも言います。 http://stackoverflow.com/a/14167897/367456 – hakre

+0

ありがとう@prodigitalson!関数から$ _SESSIONアスペクトを移動させる@hakre提案を受けた後、この最後のステップまでポップアップしなかったいくつかのエラーが見つかりました。 –

+0

"$ yourDataArray"の例を表示できますか? –

2

この(PDOまたはプリペアドステートメントをサポートする他のデータベースクライアントライブラリ)を行います:

  1. SQL INSERTのクエリを準備します。
  2. 変数をバインドします。
  3. バインド変数に対して配列をループし、反復ごとに1回実行します。

利益。

optionという単一の列を必要とする一部の表にデータを挿入する配列を持つPDOベースの例については、

まず、いくつかのデータをデータベースに挿入する:

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

どこか、のは$optionsアレイとは、データベースとの対話を気にすることを持っていると仮定しましょう。これには接続が必要です:

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

次に、挿入クエリを準備しましょう。問題になっているように、ここで名前付きパラメータを使用して、必ずこれは、あまりにも、番号のパラメータで動作します:

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

は、今度は、ここに変数にという名前のパラメータをバインドしてみましょう。変数に接頭辞(ここでは insert)があることに注意してください。上記の番号付きリストから、ポイント1)はSQL INSERTクエリを準備だから今

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

:これは実際には、入力配列のoptionキーにエイリアシングです。 2.)変数をバインドします。されている。

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

作るextractの使用がはるかにADOせずエイリアス様式で入力配列に基づいて、一度に複数の変数を設定することができる:

のみ左の値を挿入する$optionsアレイ上のループです。

フル例:

$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

単一の準備クエリを作成するのではなく、なぜこの方法を構築しますか? PDOインサートの実行をループする必要はありません。 – JM4

関連する問題