foreach内でのデータベース登録でMDB2 Errorが発生する原因と解決方法

このQ&Aのポイント
  • foreach内でのデータベース登録を行う際に、MDB2 Error: constraint violationというエラーが発生しています。
  • エラーが発生するのは、複数の商品がある場合のみで、単一の商品の場合は正常に動作します。
  • 原因としては、配列のキーが重複しているためにINSERT文生成時にエラーが発生している可能性があります。
回答を見る
  • ベストアンサー

foreach内でのデータベース登録

MDB2を使用しております。配列の値をforeach内でのデータベースに 登録をしたく以下のようなソースでやっているのですが MDB2 Error: constraint violationとエラーが出てしまいます。 長文となりますが以下が詳細です。 $products_dataのデバッグ結果 Array ( [130_df08024b_S_0] => Array ( [num] => 1 [products_id] => 130 [products_code] => df08024b [name] => 商品名1 [tax] => 84 [price] => 1680 [classcategory_name1] => S [classcategory_name2] => 0 [classcategory_id1] => 56 [classcategory_id2] => 0 [point_rate] => 10 [add_point] => 168 ) [140_df08024c_M_0] => Array ( [num] => 1 [products_id] => 140 [products_code] => df08024c [name] => 商品名2 [tax] => 53 [price] => 1050 [classcategory_name1] => M [classcategory_name2] => 0 [classcategory_id1] => 46 [classcategory_id2] => 0 [point_rate] => 10 [add_point] => 105 ) ) foreach ($products_data as $key => $val) { foreach ($val as $key2 => $val2) { // 変数に代入 $$key2 = mysql_real_escape_string($val2); } $fields2[$key] = array('order_id' => $order_id, 'product_id' => $products_id, 'product_name' => $name, 'product_code' => $products_code, 'classcategory_id1' => $classcategory_id1, 'classcategory_id2' => $classcategory_id2, 'classcategory_name1' => $classcategory_name1, 'classcategory_name2' => $classcategory_name2, 'price' => $price, 'num' => $num, 'point_rate' => $point_rate); // INSERT文生成 $res = $mdb2->extended->autoExecute(products_order_detail, $fields2[$key], MDB2_AUTOQUERY_INSERT); } print_r($fields2) 以下デバッグの結果です。思うようにデータは入っております。 Array ( [130_df08024b_S_0] => Array ( [order_id] => 370139549628 [product_id] => 130 [product_name] => 商品名1 [product_code] => df08024b [classcategory_id1] => 56 [classcategory_id2] => 0 [classcategory_name1] => S [classcategory_name2] => 0 [price] => 1680 [num] => 1 [point_rate] => 10 ) [140_df08024c_M_0] => Array ( [order_id] => 370139549628 [product_id] => 140 [product_name] => 商品名2 [product_code] => df08024c [classcategory_id1] => 46 [classcategory_id2] => 0 [classcategory_name1] => M [classcategory_name2] => 0 [price] => 1050 [num] => 1 [point_rate] => 10 ) ) 商品が1つの場合であればうまく動作するのですが2つ以上になると やはりエラーとなってしまいます。 複数の場合のみのエラーなので簡単な間違いかと思いいろいろ考え 試してみたのですが原因がわからずにいる状態です。 どのように変更すればいいものでしょうか?宜しくお願い致します。

  • dcx147
  • お礼率33% (214/636)
  • PHP
  • 回答数2
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

ざっと見てみましたが思いつきません。autoExecuteは使ったことが無いので、そこが不安ですが(^^ゞ で、ユニークキーが無いなら一番目と同じ値を続けてinsert出来ると思いますので試してみてください。それが通れば2番目の値に問題あり。それが通らなければ、autoExecuteの使い方の問題だと思います。 すいません眠いのでボケかましているかも知れません。もう寝ますので申し訳ないです。

dcx147
質問者

お礼

遅くまでお付き合い頂きありがとうございました。 phpに問題があるものかと思っておりずっと眺めてみましたが全く わからずでsqlを見直ししたところauto_incrementの指定こそは ありませんがまさかのPRIMARYKEYの指定がしてありました。 無念です・・・w しかしながら解決に至りましたのでこれにて締め切りとさせて頂きます。 ありがとうございました!

その他の回答 (1)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

「constraint violation」だったら制限違反ですね。 コードを読まずに答えていることをお詫びしておきます。 1.NOT NULLにNULLを入れた。 2.UNIQUEキーなのに同じ値を入れた。 3.PRIMARYキーなのに同じ値を入れた。 あたりが怪しいです。

dcx147
質問者

補足

>コードを読まずに答えていることをお詫びしておきます。 長文なのでお気持ちはわかりますが読んで頂けますと助かりますw >1.NOT NULLにNULLを入れた。 デバッグで確認しましたが全て入っておりました。 >2.UNIQUEキーなのに同じ値を入れた。 >3.PRIMARYキーなのに同じ値を入れた。 これは適用しておりません。 1つであれば問題ないのに2つ以上であればエラーというのが謎です^^;

関連するQ&A

  • foreachで配列を作る

    $array = array("id","name","address","tel","point","a1"); $res = $db->query($sql);  //sqlのクエリー while ($row = $res->fetchRow( DB_FETCHMODE_ASSOC )) { $data_list[]=array( $array[0]=>$row["$array[0]"], $array[1]=>$row["$array[1]"], $array[2]=>$row["$array[2]"], $array[3]=>$row["$array[3]"], $array[4]=>$row["$array[4]"], $array[5]=>$row["$array[5]"]); } をforeachを使って $array = array("id","name","address","tel","point","a1"); $res = $db->query($sql);  //sqlのクエリー while ($row = $res->fetchRow( DB_FETCHMODE_ASSOC )) { foreach(~){             //処理     } のようにかきかえたいのですがどうしたらいいでしょうか?foreachをしらべていろろやったのですがうまくいきません。よろしくおねがいします。  ちなみに$data_list[]の配列はArray ( [0] => id [1] => name [2] => address [3] => tel [4] => point [5] => a1 ) Array ( [0] => Array ( [id] => 0 [name] => ここあ [address] => 東京 [tel] => 2 [point] => 2 [a1] => 2 ) [1] => Array ( [id] => 1 [name] => 太郎 [address] => 東京 [tel] => 3 [point] => 5 [a1] => あ ) [2] => Array ( [id] => 4 [name] => 五郎 [address] => 東京 [tel] => 0 [point] => 1 [a1] => あああああ ) [3] => Array ( [id] => 5 [name] => 士郎 [address] => 神奈川 [tel] => 26 [point] => 5 [a1] => ああああああああああ ) …となります。

    • 締切済み
    • PHP
  • DBから取得したデーター+配列データーの受取り

    (過去に似たような質問をしたのですが、その続きの質問です。) よろしくお願いします。 ※セッションID(以下(3)のDBのカラム(ssid)で使用)を 発行した状態で以下を行いたいのですが、(3)がうまくいきません。 (1)商品リストのDBを以下のように作り -------------------------------------------- (テーブル:products) product_id | product_cd | name | price 1 | 10 | 本01   | 1300 2 | 11 | 本02     | 1200 3 | 20 | サプリ01    | 4800 4 | 30  | ストレッチボード | 9800 5 | 30 | 健康シューズ   | 6800 -------------------------------------------- (2)上記をmysql_fetch_arrayで取り出し<table>を作成。 その際に、商品選択をする(checkbox)と(数量)を入力する<input> を加え<form>でkaimonoKago.phpへ送信します。 (products.php) <?php (途中省略) mysql_query("set names utf8"); $sql = "select * from products "; $result = mysql_query($sql) ; ?> <form method="post" action="kaimonoKago.php"> <table> <tr> <th></th> <th>商品コード</th> <th>商品名</th> <th>価格(税込</th> <th>数量</th> </tr> <?php while($row = mysql_fetch_array($result)){ print "<tr>\n"; print "<th><input type=\"checkbox\" name=\"check[]\" value=\"".$row["product_id"]."\"></th>\n"; print "<td>".htmlspecialchars($row["product_cd"])."</td>\n"; print "<td>".htmlspecialchars($row["product_name"])."</td>\n"; print "<td>&yen;".number_format($row["price_intax"])."</td>\n"; print "<td><input type=\"text\" name=\"kazu[".$row["product_id"]."]\" size=\"3\"></td>\n"; print "<input type=\"hidden\" name=\"ssid\" value=\"".$_SESSION['ssid']."\" />\n"; print "</tr>\n"; } ?> <input type="submit" name="order" value="注文" /> </form> (3)<form>で送られてきた情報を、買い物カゴDB ----------------------------------------------- (テーブル名:kaimonoKago) (カラム: ssid, product_cd, product_name, price_intax, kazu, shoukei) ----------------------------------------------- にインサートしたいのですが、うまくいきません。正しい記述を教えて下さい。 mysql_fetch_arrayやらwhile文やら配列が2つあったりして、どのように組み立てたら いいのか、基本的な考え方も教えていただければ幸いです。 (自分がつくった、うまくいかないコード)    ↓ (kaimonoKago.php) $check=(isset($_REQUEST["check"]) and is_array($_REQUEST["check"]))?$_REQUEST["check"]:array(); $kazu=(isset($_REQUEST["kazu"]) and is_array($_REQUEST["kazu"]))?$_REQUEST["kazu"]:array(); foreach($check as $val){ if($kazu[$val]>0){ $sql = "select * from products where product_id ='" . mysql_real_escape_string($val) . "'"; $result = mysql_query($sql); while($products = mysql_fetch_array($result)){ $product_cd = $products['product_cd']; $product_name = $products['product_name']; $price_intax = $products['price_intax']; $kazu = $kazu[$val]; $shoukei = $price_intax * $kazu; $sql = "insert into kaimonoKago ( ssid, product_cd, product_name, price_intax, kazu, shoukei ) values ( '" . mysql_real_escape_string ( $_SESSION['ssid'] ) . "', '" . mysql_real_escape_string ( $product_cd ) . "', '" . mysql_real_escape_string ( $product_name ) . "', '" . mysql_real_escape_string ( $price_intax ) . "', '" . mysql_real_escape_string ( $kazu ) . "', '" . mysql_real_escape_string ( $shoukei ) . "' )"; mysql_query($sql); } } } } よろしくお願いします。

    • ベストアンサー
    • PHP
  • MDB2の操作について

    MDB2を使用しMYSQLの操作をしております。データが無いものは INSERTし、既にあるものはUPDATEしたいという状況になり調べて みたところON DUPLICATE KEY UPDATEが使えるようでした。 ここまではいいのですがON DUPLICATE KEY UPDATEを知ったのも 初めてなものでMDB2で使用したくマニュアルを見たのですが どのような構文になるのかを見つけることができず困っております。 MDB2でこれを使用するにはどのような構文になるのでしょうか? 通常のINSERTの場合ですが現状は以下のようなソースで行っています。 ※idがPRIMARY KEYです。 $fields = array('id' => 1, 'name' => 'あああ'); $res = $mdb2->extended->autoExecute(test, $fields, MDB2_AUTOQUERY_INSERT); 詳しい方いらっしゃいましたら宜しくお願い致します。

    • ベストアンサー
    • PHP
  • c言語 

    データを構造体の配列に格納したいのですが、このやり方ではできませんでした。どうすればいいですか? (ファイル内のデータを読み込んで格納しようとしています。) typedef struct dataset{ int price; char id; char name; }data; int main(void) { FILE *f = fopen("input.txt","r"); FILE *output = fopen("output.txt","w"); char order[100]; char name[100]; char id[100]; int price; int num = 0; while(fscanf(f,"%s",order) != EOF){ fscanf(f,"%s%s%d",product->name[num],product->id,&product[num].price); num++; } } return 0; } input.txt CD Kenji 300 DVD Nanako 350 PC Koki 1000 ........

  • 多次元配列で、foreachを使って、key値を

    多次元配列で、foreachを使って、key値を入れ替えているのですが、 なんで、こうなるか分かりません。  $x = array();  $x[] = array(   "id" => 1,   "name" => "JavaScript",  );  $x[] = array(   "id" => 5,   "name" => "PHP",  );  $z = array();  foreach($x as $key => $value){   $z[$value["id"]] = $value;   }  print_r($z); 配列のKEYをIDに変更しているのですが、 なんで、こうなるのでしょうか? 特に、  $z[$value["id"]] = $value; が分かりません。 例えば、foerachの途中で、var_dumpすると、 1回目だと、 ◆$key 0 ◆$value Array (  [id] => 1  [name] => JavaScript ) ◆$value["id"] 1 まではいいのですが、 ◆$z[$value["id"]] の値が見れません。 ここはどんな処理をやっているのでしょうか?

    • ベストアンサー
    • PHP
  • PHPである商品のときだけ、リンク先を変える方法

    いつもお世話になっております! 初心者な質問で申し訳ないのですが、 下記のPHPは、商品名のところに指定される、リンク先を 定義しているものなのですが、このとき、 商品IDが35と36番のときだけ、別のURLに飛ばしたいのです。 (http://domainname.com/hogehoge/item1.html など) IFで定義しないといけないと思うのですが、 何分初心者のため、どのように挿入すればいいかがわかりません。 ご教授お願いいたします!!! for ($col=0, $n=sizeof($column_list); $col<$n; $col++) { $lc_align = ''; switch ($column_list[$col]) { case 'PRODUCT_LIST_MODEL': $lc_align = ''; $lc_text = $listing->fields['products_model']; break; case 'PRODUCT_LIST_NAME': $lc_align = ''; if (isset($_GET['manufacturers_id'])) { $lc_text = '<h3 class="itemTitle"><a href="' . zen_href_link(zen_get_info_page($listing->fields['products_id']), 'cPath=' . (($_GET['manufacturers_id'] > 0 and $_GET['filter_id']) > 0 ? zen_get_generated_category_path_rev($_GET['filter_id']) : ($_GET['cPath'] > 0 ? zen_get_generated_category_path_rev($_GET['cPath']) : zen_get_generated_category_path_rev($listing->fields['master_categories_id']))) . '&products_id=' . $listing->fields['products_id']) . '">' . $listing->fields['products_name'] . '</a></h3><div class="listingDescription">' . zen_trunc_string(zen_clean_html(stripslashes(zen_get_products_description($listing->fields['products_id'], $_SESSION['languages_id']))), PRODUCT_LIST_DESCRIPTION) . '</div>' ; } else { $lc_text = '<h3 class="itemTitle"><a href="' . zen_href_link(zen_get_info_page($listing->fields['products_id']), 'cPath=' . (($_GET['manufacturers_id'] > 0 and $_GET['filter_id']) > 0 ? zen_get_generated_category_path_rev($_GET['filter_id']) : ($_GET['cPath'] > 0 ? zen_get_generated_category_path_rev($_GET['cPath']) : zen_get_generated_category_path_rev($listing->fields['master_categories_id']))) . '&products_id=' . $listing->fields['products_id']) . '">' . $listing->fields['products_name'] . '</a></h3><div class="listingDescription">' . zen_trunc_string(zen_clean_html(stripslashes(zen_get_products_description($listing->fields['products_id'], $_SESSION['languages_id']))), PRODUCT_LIST_DESCRIPTION) . '</div>'; } break; case 'PRODUCT_LIST_MANUFACTURER': $lc_align = ''; $lc_text = '<a href="' . zen_href_link(FILENAME_DEFAULT, 'manufacturers_id=' . $listing->fields['manufacturers_id']) . '">' . $listing->fields['manufacturers_name'] . '</a>'; break; case 'PRODUCT_LIST_PRICE': $lc_price = zen_get_products_display_price($listing->fields['products_id']) . '<br />'; $lc_align = 'right'; $lc_text = $lc_price;

    • ベストアンサー
    • PHP
  • テーブルデータ表示

    mysqlからデータをphpで取得し以下のような多次元配列になっています。 Array ( [0] => Array ( [id] => 116 [name] => あああ ) [1] => Array ( [id] => 58 [name] => いいい ) [2] => Array ( [id] => 89 [name] => ううう ) ) 単純にデータを表示させたく以下のようにしましたが<th>$key2</th>の箇所が上記配列の場合 2回繰り返されて表示されてしまいます。ここはフィールド名なので1回の表示でいいのですが どのように記述すれば思うような表示になるでしょうか? echo "<table border=\"1\">"; echo "<tr>"; foreach ($tmp1 as $key => $val) { foreach ($val as $key2 => $val2) { echo "<th>" . $key2 . "</th>"; //フィールド名 } } echo "</tr>"; foreach ($tmp1 as $key => $val) { echo "<tr>"; foreach ($val as $key2 => $val2) { echo "<td>" . $val2 . "</td>"; // 取得したデータをある分だけ繰り返し } echo "</tr>"; } echo "</table>";

    • ベストアンサー
    • PHP
  • arsort の key について

    こんにちは、Blackwinglsです。 ちょっと気になったので質問いたします。 以下のデータのポイント表があります。 データはSQLで order by name で取り出してます。 name point H氏 50p F氏 8p D氏 8p K氏 6p これを以下のscriptで出力すると <?php arsort($point); $count = 1; while(list($key,$val) = each($point)) { echo $key; echo ":"; echo $name[$key]; echo ":"; echo $val echo "<br>"; $count++; } ?> 3:H氏:50 2:F氏:8 1:D氏:8 4:K氏:6 と表示されますが、同じscriptを <?php arsort($point); $count = 1; while(list($key,$val) = each($point)) { echo $key; echo ":"; echo $name[$key]; echo ":"; echo $val echo "<br>"; $count++; } ?> <?php arsort($point); $count = 1; while(list($key,$val) = each($point)) { echo $key; echo ":"; echo $name[$key]; echo ":"; echo $val echo "<br>"; $count++; } ?> のように立て続けに書くと、 3:H氏:50 2:F氏:8 1:D氏:8 4:K氏:6 3:H氏:50 1:D氏:8 2:F氏:8 4:K氏:6 のように、同じ $point の場合、氏名が都度入れ替わるようです。 これって正常な動きなのでしょうか? order by name なので、氏名順に常に表示される気がするのですが・・・? 最近、php4からphp5に変更したら出たような気がするのですが、私の気のせい? どなたか情報お持ちの方、ご示唆くだされば幸いです。

    • ベストアンサー
    • PHP
  • PDOのバインドをforeachでまとめて処理したいができません…。

    いつもお世話になっております。 PHP5.2.5 --------------------------- DB(フィールドは以下3項目) ・id(primary key) ・color ・num --------------------------- //DBにインサートするデータ群(配列に格納してある) $insert_array = array('color'=>'red','num'=>6); //================================================== // *フィールド名とそれに対応するデータをバインドする。 //================================================== //================================================== // *バインド:方法1 //================================================== foreach($insert_array as $field => $value){  //確認処理  //echo $field.'<br/>';  //echo $value.'<br/>';  //バインド(foreachで、1つずつバインドしていく)  $stmt->bindParam(':'.$field,$value); } //================================================== // *バインド:方法2(↓こちらだと上手くいく。) //================================================== /* $stmt->bindParam(':'.'color',$insert_array['color']); $stmt->bindParam(':'.'num',$insert_array['num']); */ //================================================== // *バインド後、「$stmt->execute();」した結果 // *DBにインサートされたものをprint_r()にて確認 //================================================== ★方法1 Array ( [id] => 15 [color] => 6 [num] => 6 ) //--------------------------- ★方法2 Array ( [id] => 16 [color] => red [num] => 6 ) //--------------------------- ★方法1の結果の、「 [color] => 6」って一体…?! 方法2のように、同じバインド処理を手書きで繰り返す分にはうまくいくのですが、 方法1のようなforeachでまとめて処理するやり方だとうまくいきません。 方法1の問題箇所をどなたか教えて下さい。 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • php foreach 配列のソート方法

    配列のソート方法の仕方がわからず調べているのですが、なかなかできず困っております。 どなたかご教授お願いいたします。 array(5) { [0]=> array(3) { ["id"]=> string(1) "1" ["size"]=> string(5) "100" ["message"]=> string(7) "テスト1" } [1]=> array(3) { ["id"]=> string(1) "2" ["size"]=> string(5) "200" ["message"]=> string(7) "テスト2" } [2]=> array(3) { ["id"]=> string(1) "3" ["size"]=> string(5) "300" ["message"]=> string(7) "テスト3" } [3]=> array(3) { ["id"]=> string(1) "4" ["size"]=> string(5) "400" ["message"]=> string(7) "テスト4" } [4]=> array(3) { ["id"]=> string(1) "5" ["size"]=> string(4) "500" ["message"]=> string(7) "テスト5" } [5]=> array(3) { ["id"]=> string(1) "6" ["size"]=> string(5) "600" ["message"]=> string(7) "テスト6" } } foreach ($data as $key => $val) { ・ ・ ・ } となっております。foreachでループさせたときにidの降順?(1→6に表示)になるのですが、sortで昇順?(6→1に表示)にしたいです。 お分かりの方がいらっしゃいましたらお願いいたします。

    • 締切済み
    • PHP

専門家に質問してみよう