У меня есть две таблицы в базе данных MySql, одна – sales_order
а другая – sales_order_details
которая содержит детали заказа в таблице sales_order
. Очевидно, что от sales_order
до sales_order_details
отношение от sales_order
до sales_order_details
.
Когда клиент размещает заказ, первая запись производится в таблице sales_order
и на основе идентификатора auto_increment
таблицы sales_order
, соответствующая запись sales_order_details
таблицу sales_order_details
.
Я использую last_insert_id()
MySql для получения соответствующего order_id
из таблицы sales_order
, что-то вроде этого.
insert into sales_order_details(order_id, prod_id, prod_price)values(last_insert_id(), 5, 1500);
Работает. Функция last_insert_id()
извлекает последний вставленный идентификатор из соответствующей таблицы, которая уникальна для конкретного соединения (насколько я знаю).
Теперь мне нужен тот же order_id
который был восстановлен и недавно добавлен last_insert_id()
чтобы отправить его в качестве номера счета в платежную систему.
Я могу попробовать использовать функцию PHP mysql_insert_id()
но я не уверен, работает ли она как указано. Каков правильный способ получить последний идентификатор вставки, который всегда гарантирует получение конкретного идентификатора, который всегда связан с определенным порядком?
Есть два способа решения этой проблемы:
После ввода записи в sales_order:
Получите last_insert_id
и сохраните его в переменной php, затем введите это значение в соответствующие запросы.
Сохраните last_insert_id
в пользовательской переменной MySql и используйте переменную в запросе вместо last_insert_id
.
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);`
http://ca.php.net/manual/en/mysqli.insert-id.php
это собственность, которую вы ищете. Это абсолютно надёжно.
mysql_insert_id (и все функции mysql_) устарел.
Оба * LAST_INSERT_ID () * и * mysql_insert_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;
Транзакция должна обеспечивать, чтобы операции были атомарными (все это было сделано без прерывания другими процессами);
Если вы должны были сделать то же самое без транзакции или из кода приложения, количество может быть обновлено другим потоком и прочитано третьим потоком, прежде чем вы закончите обновление цены. Удовлетворение ложного «price_to_pay» для пользователя.
Вы хотели бы немного перестроить свои запросы.
sales_order
mysql_insert_id()
чтобы восстановить идентификатор записи sales_order
: $sales_order_id = mysql_insert_id()
Просто используйте mysql_insert_id()
сразу после загрузки sales_order. Вам будет хорошо.
mysql_insert_id( )
всегда возвращает идентификатор, сгенерированный для столбца AUTO_INCREMENT
предыдущим запросом. (См. Руководство по PHP )
Я не понимаю, какой именно идентификатор вы хотите получить, но чтобы получить его с помощью 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 состоит в том, что ваша система или инфраструктура не могут испортить ваши запросы, выполняя другой запрос, пока вы не знаете об этом.
1. Database CREATE TABLE MyGuests ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL, email VARCHAR(50), reg_date TIMESTAMP ) ------------------------------------------------------------------- 1. Example (MySQLi Object-oriented) ------------------------------------------------------------------- <?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDB"; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')"; if ($conn->query($sql) === TRUE) { $last_id = $conn->insert_id; echo "New record created successfully. Last inserted ID is: " . $last_id; } else { echo "Error: " . $sql . "<br>" . $conn->error; } $conn->close(); ?> ------------------------------------------------------------------- 2. Example (MySQLi Procedural) ------------------------------------------------------------------- <?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDB"; // Create connection $conn = mysqli_connect($servername, $username, $password, $dbname); // Check connection if (!$conn) { die("Connection failed: " . mysqli_connect_error()); } $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')"; if (mysqli_query($conn, $sql)) { $last_id = mysqli_insert_id($conn); echo "New record created successfully. Last inserted ID is: " . $last_id; } else { echo "Error: " . $sql . "<br>" . mysqli_error($conn); } mysqli_close($conn); ?> ------------------------------------------------------------------- 3. Example (PDO) ------------------------------------------------------------------- <?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDBPDO"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')"; // use exec() because no results are returned $conn->exec($sql); $last_id = $conn->lastInsertId(); echo "New record created successfully. Last inserted ID is: " . $last_id; } catch(PDOException $e) { echo $sql . "<br>" . $e->getMessage(); } $conn = null; ?>