我遇到了这个SIMPLE存储过程的问题。我想在变量中保存 LAST_INSERT_ID ,然后将其分配给下一个插入。
NaN
我真的不知道该怎么做。
答案 0 :(得分:3)
您需要声明一个变量并使用set
来分配值,例如:
DELIMITER //
CREATE PROCEDURE Adda(
Name varCHAR(45),Surrname varCHAR(45),City varCHAR(45),PhoneNumber varCHAR(45),photo varCHAR(45))
BEGIN
DECLARE last_insert_id INT;
START TRANSACTION;
INSERT INTO Personal(Name,Surrname)
VALUES(Name,Surrname);
SET last_insert_id = LAST_INSERT_ID(); --assignment
INSERT INTO Addres(Id_Personal_Address,Country, City)
VALUES(last_insert_id,Country,City);
INSERT INTO Images(Id_Personal_Address,photo)
VALUES(last_insert_id, Photo); -- use
COMMIT;
END//
DELIMITER ;
答案 1 :(得分:1)
你知道你可以调用LAST_INSERT_ID()作为任何表达式的一部分,包括下一个INSERT:
INSERT INTO Addres(Id_Personal_Address,Country, City)
VALUES(LAST_INSERT_ID(),Country,City);
INSERT INTO Images(Id_Personal_Address,photo)
VALUES(LAST_INSERT_ID(), Photo); -- and here use it
但LAST_INSERT_ID()始终返回上一次INSERT生成的id值。如果您的地址插入具有自动加密钥,则这将成为生成的新“最后”ID。
因此,如果您需要多次使用该值,则应为其声明一个局部变量,因为INSERT into Images会更改最后一个插入ID。
您可以在过程中声明局部变量。此必须在BEGIN
BEGIN
DECLARE personalId INT DEFAULT NULL;
然后再使用它:
SET personalId = LAST_INSERT_ID();
INSERT INTO Addres(Id_Personal_Address, Country, City)
VALUES(personalId, Country, City);
INSERT INTO Images(Id_Personal_Address, photo)
VALUES(personalId, Photo);
提示:选择与列名不同的变量名称,以使代码清晰。
那么在变量之前使用@
是什么意思?
您可以先使用@addressId
之类的变量而不先使用DECLARE
。但变量将变为User-Defined Session Variable,并在程序退出后保留其值。除非您不小心覆盖会话范围中的变量,否则不会造成任何损害。或者,如果您编写一个调用另一个存储过程的存储过程,并且它们都尝试使用相同的变量名。
使用DECLARE
创建一个真正属于过程范围的变量。
更令人困惑的是,您可以声明给定名称的变量,然后使用相同的名称和@
但这是一个不同的变量。
例如,这是在MySQL 8.0.0上测试的演示:
mysql> delimiter ;;
mysql> create procedure foo()
-> begin
-> declare last_insert_id int default 0;
-> set @last_insert_id = 1234;
-> select last_insert_id;
-> end;;
mysql> delimiter ;
mysql> call foo();
+----------------+
| last_insert_id |
+----------------+
| 0 |
+----------------+
mysql> select @last_insert_id;
+-----------------+
| @last_insert_id |
+-----------------+
| 1234 |
+-----------------+