Retrieve insert id in stored procedure with mysql - mysql

I have stored procedure for insert booking record with details like booking_id, name, r_id, t_id etc. Now I want to know how to retrieve insert id of this record.
Stored procedure allow LAST_INSERT_ID only.
Here MYSQL_INSERT_ID() not working.
But here at a time two users perform booking then last record is different.
Please help me how to get insert record id for the booking through Stored Procedures in my sql ..

You can capture the last_insert_id() value in different ways.
Define an 'OUT' parameter in procedure signature, with proper data type.
Now, after executing INSERT INTO..., execute set out_param := last_inser_id();
Now you can read value of 'OUT' parameter from the calling program or sql code body.
Example 1:
delimiter //
create procedure sp_so_q24075108( IN param1 int, ..., OUT param_auto_id int )
begin
insert
into table_name( col2, col3, ... )
values ( param1, param2, ... );
set param_auto_id := last_insert_id();
end;
//
delimiter ;
call sp_so_q24075108( 6, ..., #last_generated_id );
select #last_generated_id;
OR
Capture 'LAST_INSERT_ID()' into user variable after executing 'INSERT' statement.
Now you can read value of 'OUT' parameter from the calling program or sql code body.
Example 2:
delimiter //
create procedure sp_so_q24075108( IN param1 int, ... )
begin
insert
into table_name( col2, col3, ... )
values ( param1, param2, ... );
set #auto_id := last_insert_id();
end;
//
delimiter ;
call sp_so_q24075108( 6, ... );
select #auto_id;
Reference:
CREATE PROCEDURE Syntax

Related

Insert into table (select from another table) and some parameters

I want to insert into one table selecting values from another table and some with paramters.
CREATE PROCEDURE `insertuser`(
IN `param1` VARCHAR(50)
)
BEGIN
insert into users(firstname,lastname,email)
select name,nickname,#param1 from members
where id=3;
END
I fill param1 but the query insert null to email
what I need to do?
# symbol is used to define Session variables (accessible to the Session everywhere). You don't need to use # here, as you are using the input parameter value from the Stored procedure.
Try the following instead:
DELIMITER $$
CREATE PROCEDURE `insertuser`(IN `param1` VARCHAR(50))
BEGIN
INSERT INTO users(firstname,lastname,email)
SELECT name,nickname,param1 -- remove # from #param1 here
FROM members
WHERE id=3;
END$$
DELIMITER ;

MySQL stored procedure - How to get last insert id

I have created one stored procedure which inserts a record into table and gets auto incremented ID of that record. Here I am getting an syntax error while setting LAST_INSERT_ID() into a variable.
ERROR 1064 (42000): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near ');
SET _orderId = SELECT LAST_INSERT_ID(); END' at line 5
Please help me to solve this issue. Thanks in Advance.
My code is like below:
DELIMITER //
CREATE PROCEDURE placeOrder(IN _cartId INT, IN _createdBy INT)
BEGIN
DECLARE _orderId INT;
-- insert into order
INSERT INTO `TBL_ORDER`(`DealerId`, `OrderNo`, `CreatedBy`)
VALUES ((SELECT DealerId FROM TBL_SHOPPING_CART WHERE Id = _cartId), UNIX_TIMESTAMP(), _createdBy));
SET _orderId = SELECT LAST_INSERT_ID();
END//
DELIMITER ;
Try this.
delimiter //
CREATE PROCEDURE placeOrder(IN _cartId INT,IN _createdBy INT)
BEGIN
SET #orderId = '';
-- insert into order
INSERT INTO `TBL_ORDER`(`DealerId`, `OrderNo`, `CreatedBy`) VALUES ((SELECT DealerId FROM TBL_SHOPPING_CART WHERE Id = _cartId),UNIX_TIMESTAMP(),_createdBy));
SELECT LAST_INSERT_ID() INTO #orderId;
END//
delimiter ;
OR
delimiter //
CREATE PROCEDURE placeOrder(IN _cartId INT,IN _createdBy INT)
BEGIN
-- insert into order
INSERT INTO `TBL_ORDER`(`DealerId`, `OrderNo`, `CreatedBy`) VALUES ((SELECT DealerId FROM TBL_SHOPPING_CART WHERE Id = _cartId),UNIX_TIMESTAMP(),_createdBy);
SELECT LAST_INSERT_ID() AS '_orderId ';
END//
delimiter ;
You should make sure that your application is not having a global connection or shared connection. As last_insert_it() will return the last generated AI value it can be from any table. Especially if your host application is using async TASKs
Consider following scenario
Your application saves gps location every second => generating new AI value
You're trying above SP to insert a value => Generating new AI value
Between your insert and read last_insert_id, your application logs gps location again and created new AI value.
Now guess what happens? you get the last inserted id from the gps table not from your SP.
usually insert's are fast, but assume your SP had to wait for a table lock and got delayed. In such case, you will receive wrong ID.
Safest way can be to escapsulate your SP work within a transaction and get the max value of your AI column (assuming it's an unsigned AI column).
Try:
...
-- SET _orderId = SELECT LAST_INSERT_ID();
SET _orderId = LAST_INSERT_ID();
SELECT _orderId;
...
or
...
-- SET _orderId = SELECT LAST_INSERT_ID();
SET _orderId = (SELECT LAST_INSERT_ID());
SELECT _orderId;
...

How can I pass quoted value to a stored procedure

I have a stored procedure which refreshes table1 by selecting a bunch of fields from table2. The issue I have is that when I run the procedure it does not update table1.
Here is the procedure call statement:
CALL `dabaseName`.`p_refresh_table1`(<{loc_id VARCHAR(5)}>);
So if I call the procedure like so:
CALL `databaseName`.`p_refresh_table1`('12');
or like so:
CALL `databaseName`.`p_refresh_table1`(12);
It does NOT update results to table1
I have found the reason behind this so if I expand the SQL in this procedure and manually pass the id I see the following :
The SQL is:
DELETE FROM table1 where id=loc_id;
INSERT INTO selling table
(column1,
column2,
column3,
..
..
.
)
(SELECT DISTINCT table2.id,
..
..
..
..
);
If I run the sql with loc_id substituted with '12' (quoted) it works as expected
However If I run it with loc_id substituted with 12 (unquoted) it does not update table1.
So I need to know how I can pass '12' instead of 12 to the value of loc_id.
The procedure create statement starts like so:
DELIMITER $$
CREATE DEFINER=`userName`#`%` PROCEDURE `p_refresh_table1`(loc_id VARCHAR(5))
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
SET sql_log_off = 1;
START TRANSACTION;
Thanks

How can I ignore the resultset of a stored procedure in a trigger?

My question is basically this one but for MySQL instead of SQL Server.
I have a stored procedure which returns a result set.
CREATE STORED PROCEDURE CreateFoo (input_id INT)
DECLARE result_id INT;
INSERT INTO FooTable (blah blah) VALUES (blah blah);
SELECT LAST_INSERT_ID() INTO result_id;
INSERT INTO OtherTable (x, y, blah) VALUES (input_id, result_id, blah);
SELECT result_id;
END
I have a trigger on another table
CREATE TRIGGER MyTrigger AFTER INSERT ON Bar
FOR EACH ROW
BEGIN
CALL CreateFoo (NEW.a);
CALL CreateFoo (NEW.b);
END
But now when I insert into Bar I get
ERROR 1415 (0A000) at line 5365: Not allowed to return a result set from a trigger
I understand why this is happening, now I need to quietly ignore the resultsets from CreateFoo.
In SQL Server the answer is to create a temporary table and INSERT INTO Temp CALL CreateFoo but apparently you can't do this in MySql.
Is there a way to drop the resultset from the trigger in MySql?
The only way I can think of is using OUT parameters (and this is actually the "clean" way of returning a result from a procedure, when it's just a single row).
Rewrite your procedure like this:
CREATE STORED PROCEDURE CreateFoo (IN input_id INT, OUT result INT)
INSERT INTO FooTable (blah blah) VALUES (blah blah);
SET result = LAST_INSERT_ID();
END
or
CREATE STORED PROCEDURE CreateFoo (IN input_id INT, OUT result INT)
INSERT INTO FooTable (blah blah) VALUES (blah blah);
SELECT LAST_INSERT_ID() INTO result;
END
You'd execute the procedure like this then:
CALL CreateFoo(5, #my_result);
When you need the last insert id, you can use it with
SELECT #my_result;
in the same session.
In your trigger of course you simply ignore the variable.
CREATE TRIGGER MyTrigger AFTER INSERT ON Bar
FOR EACH ROW
BEGIN
CALL CreateFoo (NEW.a, #variable_you_donT_care_about);
CALL CreateFoo (NEW.b, #variable_you_donT_care_about);
END
Read more about IN, OUT and INOUT parameters here.

Trigger not working as expected

I trying execute an trigger on mysql database.
The command executes successfully, but the trigger not working.
DELIMITER #
CREATE TRIGGER generate_coupon AFTER INSERT ON order
FOR EACH ROW
BEGIN
DECLARE userid, couponvalue INT;
DECLARE couponcode VARCHAR;
SELECT idUser INTO userid FROM indication WHERE email = NEW.email;
SET couponvalue = 20;
SET couponcode = 'abc123';
INSERT INTO coupon(idUser,idOrder,couponvalue,couponcode) values(userid, NEW.id, couponvalue, couponcode);
END#
DELIMITER ;
I suspect your problem arises from the collisions between your variables couponvalue and couponcode with the same-named columns in your coupon table. As documented under Local Variable Scope and Resolution:
A local variable should not have the same name as a table column.
You could simplify your trigger to the following and, in so doing, avoid this problem entirely:
CREATE TRIGGER generate_coupon AFTER INSERT ON order FOR EACH ROW
INSERT INTO coupon
(idUser, idOrder, couponvalue, couponcode)
SELECT idUser, NEW.id, 20, 'abc123'
FROM indication
WHERE email = NEW.email
;