In an SQL function I want to create multiple records based on the parameters passed into the function, for example the function takes a member primary ID, a date/time stamp and a number specifying the number of records to create.
I could of course create a loop to perform the inserts, however I am curious to know if there is a way to get the server engine to create a specific number of records automatically ?
My function so far:
CREATE DEFINER=`root`@`localhost` FUNCTION `reserveTickets`(idMbr BIGINT(11),
dtWhen DATETIME, intTickets INT(11)) RETURNS varchar(24) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
BEGIN
DECLARE dtStartRef DATETIME;
DECLARE idMbrVerified BIGINT(11);
DECLARE intTicket INT(11);
/*Initialise reference time*/
SET dtStartRef = NOW(3);
/*Is member id valid?*/
SELECT id INTO idMbrVerified FROM tblMembers WHERE id=idMbr;
IF ISNULL(idMbrVerified) THEN
RETURN 0;
END IF;
/*Is date/time valid, can't be older that 60 seconds?*/
IF SECOND(TIMEDIFF(NOW(), dtWhen)) > 60 THEN
RETURN 0;
END IF;
/*Is the number of tickets valid, must be at least 1?*/
IF intTickets <= 0 THEN
RETURN 0;
END IF;
/*Create the records*/
SET intTicket = 0;
insertTicket: LOOP
IF intTicket < intTickets THEN
INSERT INTO tblTickets (idMbr, dtWhen) VALUES (idMbr, dtWhen);
ELSE
LEAVE insertTicket;
END IF;
SET intTicket = intTicket + 1;
END LOOP insertTicket;
RETURN TIMESTAMPDIFF(MICROSECOND, dtStartRef, NOW(3)) / 100000;
END
2
Answers
Can you try below adding instead of using
RETURN 1;
?Here’s another solution. I create a JSON array with a number of elements equal to the tickets requested. It doesn’t matter what values are in this array, it’s the length of the array that is important.
I convert that array to a set of rows using JSON_TABLE(), and use that as a source for an
INSERT...SELECT
statement, inserting a set of rows in one statement, without using a loop.By joining to the
tblMembers
table, it will produce zero rows if there is no member matching the input.I also followed a habit of naming the function arguments differently than any columns referenced by the query.
I tested this with MySQL 8.2. In my test, the timestampdiff returns wildly erratic values, sometimes even resulting a negative diff. I’m not going to attempt to explain that.
But the time reported by the client is consistently about 0.24 or 0.25 seconds.