Reputation: 33
I got a problem with this SIMPLE stored procedure. I want to save LAST_INSERT_ID in a variable and then assign it for next insert.
DELIMITER //
CREATE PROCEDURE Adda(
Name varCHAR(45),Surrname varCHAR(45),City varCHAR(45),PhoneNumber varCHAR(45),photo varCHAR(45))
BEGIN
START TRANSACTION;
INSERT INTO Personal(Name,Surrname)
VALUES(Name,Surrname);
INSERT INTO Addres(Id_Personal_Address,Country, City)
VALUES(LAST_INSERT_ID(),Country,City);
--i think here i should assign LAST_INSER_ID to variable
INSERT INTO Images(Id_Personal_Address,photo)
VALUES(Photo); -- and here use it
COMMIT;
END//
DELIMITER ;
I really don't know how to do this.
Upvotes: 3
Views: 6104
Reputation: 562300
You know you can call LAST_INSERT_ID() as part of any expression, including the next 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
But LAST_INSERT_ID() always returns the id value generated by the last INSERT. If your insert to Address has an auto-inc key, this becomes the new "last" id generated.
So if you need to use the value more than once, you should declare a local variable for it, because the INSERT into Images would change the last insert id.
You can declare a local variable in a procedure. This must come right after the BEGIN
BEGIN
DECLARE personalId INT DEFAULT NULL;
Then use it later:
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);
Tip: Choose a variable name that is distinct from your column names to make your code clear.
So what's the deal with using @
before a variable?
You can use a variable like @addressId
without doing a DECLARE
first. But the variable will become a User-Defined Session Variable and will retain its value after your procedure exits. No harm done, unless you accidentally overwrite variables from the session scope. Or if you write a stored procedure that calls another stored procedure, and both of them are trying to use the same variable name.
Using DECLARE
creates a variable that is truly local to the scope of the procedure.
What's even more confusing is that you can declare a variable of a given name, and then use the same name with an @
but that's a different variable.
For example, here's a demo tested on 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 |
+-----------------+
Upvotes: 2
Reputation: 30819
You need to declare a variable and use set
to assign the value, e.g.:
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 ;
Upvotes: 4