1

I have written the following stored procedure:

DELIMITER $$
CREATE PROCEDURE `getroom`(OUT `free_room` INT)
BEGIN

    SELECT room INTO free_room FROM admins WHERE free = 1 LIMIT 1 FOR UPDATE;
    UPDATE admins SET free = 0 WHERE room = free_room;

END$$
DELIMITER ;

I am trying to query the table for free rooms, lock the row so other users cannot query it at the same time, and set it as not free at the end.

My questions are:

1) How can I call a stored procedure and get the free_room value automatically (as if i ran a SELECT statement) without doing an additional SELECT statement?

2) Since I am not passing any arguments (don't have "IN" values), why can't I run CALL getroom() succssfully? I get the following error:

Incorrect number of arguments for PROCEDURE getroom; expected 1, got 0

Hope my questions are clear enough!

4
  • What's the point of this? Commented May 22, 2016 at 8:30
  • 1
    ad 2) note that the procedure really has one parameter - the one over which the result is returned. So, you need to call the procedure with CALL getroom(@somevar). Afterwards, the result will be available in @somevar. Commented May 22, 2016 at 8:30
  • Ok, so the parameter is needed for the OUT value. For my first question, is there a way to CALL getroom(@somevar) and get a return value without having to do CALL getroom(@somevar); SELECT @somevar;? Commented May 22, 2016 at 8:35
  • try to create a FUNCTION having return statement to achieve the same. Commented May 22, 2016 at 9:47

3 Answers 3

1

You can create function instead:

DELIMITER $$
CREATE FUNCTION `getroom`() RETURNS INT
BEGIN
    DECLARE free_room INT;
    SELECT room INTO free_room FROM admins WHERE free = 1 LIMIT 1 FOR UPDATE;
    UPDATE admins SET free = 0 WHERE room = free_room;
    RETURN free_room;
END$$
DELIMITER ;

and then just use:

SELECT getroom();
Sign up to request clarification or add additional context in comments.

2 Comments

This did the job! will it also row lock so it cannot be read by other users while it is updating?
Yes, the SELECT FOR UPDATE should lock the row, until it is updated with the next UPDATE statement.
0

Try:

DELIMITER $$

CREATE PROCEDURE `getroom`()
BEGIN 
    SELECT @free_room := room
    FROM admins
    WHERE free = 1
    LIMIT 1
    FOR UPDATE;

    UPDATE admins
    SET free = 0
    WHERE room = @free_room;   
END$$

DELIMITER ;

Comments

0
DELIMITER $$
CREATE PROCEDURE `getroom`()
BEGIN 
DECLARE free_room INT;  
    SELECT room INTO free_room FROM admins WHERE free = 1 LIMIT 1 FOR UPDATE;
    UPDATE admins SET free = 0 WHERE room = free_room;
    SELECT free_room;
END$$
DELIMITER ;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.