0

MySql データベースに 2 つのテーブルがあります。1 つはテーブル内sales_ordersales_order_details注文の詳細を含むsales_orderテーブルです。sales_order明らかに、 からへの 1 対多の関係がありsales_order_detailsます。

顧客が注文すると、最初のエントリがテーブルに作成され、テーブルのID にsales_order基づいて、対応するエントリがテーブルに作成されます。auto_incrementsales_ordersales_order_details

last_insert_id()MySql関数を使用して、テーブルから対応するものを取得しています。このようなものですorder_idsales_order

insert into sales_order_details(order_id, prod_id, prod_price)values(last_insert_id(), 5, 1500);

それは働いています。このlast_insert_id()関数は、特定の接続に固有のそれぞれのテーブルから最後に挿入された ID を取得します (私の知る限り)。

ここで、請求書番号として支払いシステムに送信する関数order_idによって最後に取得および挿入されたものと同じものが必要です。last_insert_id()

PHP 関数を試してみることはできますmysql_insert_id()が、指定どおりに機能するかどうかはわかりません。特定の注文に常に関連付けられている特定の ID を取得することを常に保証する最後の挿入 ID を取得する正しい方法は何ですか?

4

7 に答える 7

1

これを解決する方法は2つあります。

sales_orderにエントリを挿入した後:

  1. を取得last_insert_idしてphp変数に格納し、この値を関連するクエリに挿入します。

  2. last_insert_idをMySqlユーザー定義変数に格納し、クエリで。の代わりに変数を使用しますlast_insert_id

オプション2のサンプルコード

SET @last_order_id = last_insert_id();

insert into sales_order_details (order_id, prod_id, prod_price)
values (@last_order_id, 5, 1500);`

insert into sales_invoice (order_id, invoice_id)
values (@last_order_id, 1);`
于 2012-05-17T22:45:49.013 に答える
1

http://ca.php.net/manual/en/mysqli.insert-id.php

あなたが探している物件です。それは完全に信頼できます。

mysql_insert_id(およびすべてのmysql_関数)は非推奨になりました。

于 2012-05-17T22:46:51.080 に答える
1

*LAST_INSERT_ID()* と *mysql_insert_id()* の両方が宣伝どおりに機能します。つまり、現在のセッション/接続中に任意のテーブルに挿入された最後の ID を取得します。

この ID を取得する前に複数の自動インクリメント テーブルに挿入しない限り、それが正しいものであると確信できます。

また、同じテーブルに複数の値を挿入する場合も注意してください。最初の値の値を受け取りますが、必ずしも連続しているわけではありません (別のセッション/接続でもいくつかの新しいレコードが挿入された可能性があります)。

私は通常、次のようなことをするのが好きです:

START TRANSACTION;
    INSERT INTO sales_order ...;
    SET @last_order = LAST_INSERT_ID();
    INSERT INTO sales_order_details (order_id) VALUES ($last_order);
    SELECT @last_order;
COMMIT;

このクエリの結果セットには、最後の注文の値を保持する単一の列と単一の行が含まれている必要があります。

しかし、繰り返しになりますが、私は通常、何よりも更新のトランザクションの安全性のためにこれを行います。

START TRANSACTION;
    SELECT * FROM sales_order WHERE order_id = 2 FOR UPDATE;
    UPDATE sales_order_details SET quantity = 9 WHERE order_id = 2 AND prod_id = 3;
    UPDATE sales_order SET price_to_pay = (SELECT SUM(quantity*price) FROM sales_order_details WHERE order_id = 2);
COMMIT;

トランザクションは、操作がアトミックであることを保証する必要があります (すべてが他のプロセスによって中断されることなく行われます)。

トランザクションなしで、またはアプリケーション コードから同じことを行うと、価格の更新が完了する前に、数量が別のスレッドによって更新され、3 番目のスレッドによって読み取られる可能性があります。ユーザーに偽の「price_to_pay」を与える。

于 2012-05-17T22:50:31.950 に答える
0

mysql_insert_id( )AUTO_INCREMENTのクエリによって列に対して生成されたIDを常に返します。(PHPマニュアルを参照してください)

どのIDを取得するかは正確にはわかりませんが、PHPを使用して取得するには、常にクエリの直後に取得する必要があります。例えば:

// Query A

mysql_query( 'INSERT INTO table_a ( id, name ) VALUES ( NULL, "Henry" )' );
$idA = mysql_insert_id( );

// Query B

mysql_query( 'INSERT INTO table_b ( id, name, a_id ) VALUES ( NULL, "Wotton", ' . $idA . ' )' );
$idB = mysql_insert_id( );

// Query C
mysql_query( 'INSERT INTO table_c ( id, name, a_id ) VALUES ( NULL, "Rick", ' . $idA . ' )' );

それらをPHP変数に格納することの利点は、システムまたはフレームワークが、気づいていないときに別のクエリを実行してクエリを台無しにできないことです。

于 2012-05-17T22:46:03.860 に答える
0

クエリを少し再構築する必要があります。

  1. sales_orderレコードをテーブルに挿入します
  2. php関数を使用して、レコードmysql_insert_id()のIDを取得します。sales_order$sales_order_id = mysql_insert_id()
  3. 挿入を次のように書き直します。`insertintosales_order_details(order_id、prod_id、prod_price)values($ sales_order_id、5、1500);
于 2012-05-17T22:46:51.200 に答える
0

mysql_insert_id()sales_orderを挿入した直後に使用してください。大丈夫です。

于 2012-05-17T22:46:57.450 に答える