1

質問の下部にある「マイコード」にスキップして、ポイントに直行してください。


$con = mysql_connect('localhost', 'mysql_user', 'mysql_password');


一般的な例:

このように、単一mysql_queryの 内で複数のクエリ文字列を実行できます...

mysql_query("
    INSERT INTO table_one (a,b,c) VALUES (1,2,3);
    INSERT INTO table_two (x,y,z) VALUES (7,8,'a text value');
    ", $con);

このように、各クエリ文字列に複数の行を追加できます...

mysql_query("
    INSERT INTO table_one (a,b,c) VALUES (1,2,3), (2,3,1), (3,1,2);
    INSERT INTO table_two (x,y,z) VALUES (7,8,9), (8,9,7), (9,7,8);
    ", $con);

このような値の配列で...

$array(
  [0] => array(1,2,3),
  [1] => array(2,'text',1),
  [2] => array(3,1,2)
);

...クエリ文字列は、次のようにループを使用して動的に作成できます...

$a = "INSERT INTO table_one (a,b,c) VALUES ";
foreach($array as $val){
  $a .= "(". implode(",",$val) ."),";
}
$a = trim($a, ",") . ";";

質問:

2 番目のクエリ文字列によって挿入された各行が最初のクエリ文字列によって挿入された対応する行を参照できるように、複数の INSERT クエリ文字列をそれぞれ複数の行で実行する単一の MySQL クエリを作成する方法。したがって$var、このスニペットでは、最初の INSERT の auto_increment 行 ID に対応します。

mysql_query("
    INSERT INTO table_one (a,b,c) VALUES (1,2,3), (2,3,1), (3,1,2);
    INSERT INTO table_two (x,y,z) VALUES ($var,8,9), ($var,9,7), ($var,7,8);
    ", $con);

私のコード:

これは私のコードの簡略化されたバージョンです...

$q1 = "INSERT INTO `table_one` (t1c1,t1c2) VALUES ";
$q2 = "INSERT INTO `table_two` (t2c1,t2c2,t2c3) VALUES ";

foreach($array as $item){
  $q1 .= "('". $item ."','blah'),";
  $q2 .= "('". $row_ID_from_first_insert ."','something','whatever'),";
}

$q1 = trim($q1,",") .";";
$q2 = trim($q2,",") .";";
$q = $q1.$q2;

mysql_query($q, $this->connect);

生成する安全な方法は何$row_ID_from_first_insertですか?

私の理解LAST_INSERT_ID()では、単一のクエリ文字列で複数の行が挿入されると、最初に挿入された行 ID のみが返されるため、クエリ文字列での使用は機能しません。LAST_INSERT_ID()+1foreach ループで where1をインクリメンタル変数に置き換えても安全ですか? 異なるユーザーから同時に複数の送信が行われた場合はどうなりますか?

4

2 に答える 2

2

id通常、挿入された行の値をフェッチして戻す必要があります。これは、事前に手続き的に生成できるキーの代わりに使用される別のキーを作成できない場合を除きます。

複数の行をINSERT持つステートメントは大幅に高速ですが、支払う代償は精度の欠如です。値が順番に発行される場合id(これはデフォルトの動作です)、は挿入された最初の行のIDを表すと合理的に確信できるLAST_INSERT_ID()ため、インデックスから始めて、提案した方法を使用して行のIDを計算できます。 0。

LAST_INSERT_ID()この値は接続ごとであるため、複数の送信は結果に影響を与えないことに注意してください。同じデータベースハンドルで後続のクエリを実行した場合にのみ変更されます。他のリクエストでの操作は影響しません。

クラスタ化されたデータベースまたはマルチマスターのデータベースは、非シーケンシャル識別子を発行する場合があります。その場合、これは機能しません。INSERT IGNOREこれは、実際に挿入された行の数が提供された行の数よりも少ない可能性がある状況でも信頼できません。

于 2012-10-24T21:56:12.270 に答える
0

LAST_INSERT_ID() は、同じ接続ハンドルからの成功した各クエリの最後に生成されます。したがって、サンプル コードでは、探している結果が得られません。下記参照:

mysql_query("
    INSERT INTO table_two (x,y,z) VALUES (LAST_INSERT_ID(),8,9), (LAST_INSERT_ID(),9,7), (LAST_INSERT_ID(),7,8);
", $con);

上記の結果は次のようになります (x は LAST_INSERT_ID() が生成する値です)。

 x    y    z
 5    8    9
 5    9    7
 5    7    8

例で使用したのと同じ形式を使用して、求める結果を受け取るには(SQL インジェクションのリスクがあるためお勧めしません - 代わりに mysqli を使用します)、次のように実行できます。

 mysql_query("
    INSERT INTO table_two (x,y,z) VALUES (LAST_INSERT_ID(),8,9);
    INSERT INTO table_two (x,y,z) VALUES (LAST_INSERT_ID(),9,7);
    INSERT INTO table_two (x,y,z) VALUES (LAST_INSERT_ID(),7,8); 
", $con);

これにより、次のようになります (x は LAST_INSERT_ID() が生成する値です)。

 x    y    z
 5    8    9
 6    9    7
 7    7    8
于 2016-10-29T18:30:48.603 に答える