Strange loop behavior in mysql cause missing values - mysql

Hope you are fine. I usually have to create databases for my studies and to make tests and homework,
Main question
I coded a for loop for a foreign key and apparently it gave a group of each 8 rows followed by 8 rows with null value in a sort of cycle; despite the fact I ran the procedure several times.
Is just me ?
Code
CREATE DATABASE Taller2;
CREATE TABLE numeros (
numero INT NOT NULL,
CONSTRAINT XPKnumeros
PRIMARY KEY CLUSTERED (numero));
USE Taller2;
CREATE OR REPLACE VIEW generator_8
AS SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL
SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL
SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 ;
USE Taller2;
CREATE OR REPLACE VIEW generator_64
AS SELECT ( hi.n * 16 + lo.n ) AS n
FROM generator_8 lo
, generator_8 hi;
USE Taller2;
INSERT INTO numeros(numero)
SELECT n FROM generator_64 WHERE n <= 50;
-- It should give me a list of 1 to 50
select * from taller2.numeros
Then I coded this two tables:
USE Taller2;
CREATE TABLE Taller2.T1 (
ID INT NOT NULL AUTO_INCREMENT
,Nombre VARCHAR(30) NULL
,dia DATE NOT NULL
,numerox FLOAT DEFAULT (RAND()*RAND()),
PRIMARY KEY (ID)
);
CREATE TABLE Taller2.T2 (
ID INT NOT NULL AUTO_INCREMENT
,IDT1 INT NULL
,Nombre VARCHAR(30) NULL
,dia DATE NOT NULL
,numerox FLOAT DEFAULT (RAND()*RAND()),
PRIMARY KEY (ID),
FOREIGN KEY (IDT1) REFERENCES Taller2.T1(ID)
);
Then these two procedures using dynamic sql:
USE Taller2;
DELIMITER //
CREATE PROCEDURE InsertData(IN Tabla VARCHAR(3))
BEGIN
DECLARE i INT DEFAULT 1;
SET #cod_sql = CONCAT('INSERT INTO Taller2.',Tabla,' (dia,Nombre) VALUES (?,CONCAT("Animal",?));');
WHILE (i <= 50) DO
PREPARE s1 from #cod_sql;
SET #parametro1 = DATE_ADD(curdate(), INTERVAL FLOOR(RAND()*(10-0)+0) DAY);
SET #parametro2 = CONVERT(FLOOR(RAND()*(10-0) + 0),CHAR);
EXECUTE s1 USING #parametro1,#parametro2;
SET i = i+1;
END WHILE;
END;
//
DELIMITER ;
-- DROP PROCEDURE InsertData;
-- Inserting Data
CALL InsertData('T1');
CALL InsertData('T2');
CALL Insertfk();
-- Showing the data
SELECT * FROM taller2.t1;
SELECT * FROM taller2.t2;
DELIMITER //
CREATE PROCEDURE Insertfk()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE (i <= 50) DO
UPDATE taller2.t2 -- I know this is too raw but I was in a hurry
SET IDT1 = ( select numero from taller2.numeros WHERE numero = i)
WHERE ID = i;
SET i = i+1;
END WHILE;
END;
//
DELIMITER ;
CALL InsertData('T1');
CALL InsertData('T2');
CALL Insertfk();
SELECT * FROM taller2.t1;
SELECT * FROM taller2.t2;
And the following lines contained nulls Which I manually fixed because they werent too many
UPDATE `taller2`.`t2` SET `IDT1` = '9' WHERE (`ID` = '9');
UPDATE `taller2`.`t2` SET `IDT1` = '10' WHERE (`ID` = '10');
UPDATE `taller2`.`t2` SET `IDT1` = '11' WHERE (`ID` = '11');
UPDATE `taller2`.`t2` SET `IDT1` = '12' WHERE (`ID` = '12');
UPDATE `taller2`.`t2` SET `IDT1` = '13' WHERE (`ID` = '13');
UPDATE `taller2`.`t2` SET `IDT1` = '14' WHERE (`ID` = '14');
UPDATE `taller2`.`t2` SET `IDT1` = '15' WHERE (`ID` = '15');
UPDATE `taller2`.`t2` SET `IDT1` = '25' WHERE (`ID` = '25');
UPDATE `taller2`.`t2` SET `IDT1` = '26' WHERE (`ID` = '26');
UPDATE `taller2`.`t2` SET `IDT1` = '28' WHERE (`ID` = '28');
UPDATE `taller2`.`t2` SET `IDT1` = '29' WHERE (`ID` = '29');
UPDATE `taller2`.`t2` SET `IDT1` = '30' WHERE (`ID` = '30');
UPDATE `taller2`.`t2` SET `IDT1` = '31' WHERE (`ID` = '31');
UPDATE `taller2`.`t2` SET `IDT1` = '41' WHERE (`ID` = '41');
UPDATE `taller2`.`t2` SET `IDT1` = '42' WHERE (`ID` = '42');
UPDATE `taller2`.`t2` SET `IDT1` = '43' WHERE (`ID` = '43');
UPDATE `taller2`.`t2` SET `IDT1` = '44' WHERE (`ID` = '44');
UPDATE `taller2`.`t2` SET `IDT1` = '45' WHERE (`ID` = '45');
UPDATE `taller2`.`t2` SET `IDT1` = '46' WHERE (`ID` = '46');
UPDATE `taller2`.`t2` SET `IDT1` = '47' WHERE (`ID` = '47');
Any idea why?
I have MySQL 8.0 and
this is the processor: Intel(R) Core(TM) i7-6600U CPU # 2.60GHz 2.81 GHz
This is the Ram: 8.00 GB (7.88 GB usable)
Thanks,

I think in your trailer table column name is numerox
but in ur select query in procedure it ' numero

Related

ERROR #1054 - Unknown column 'program_id' in 'NEW

Tring to achieve-
I am trying to update color_status in tb_sites_3 (3 will be dynamic based on program_id which we will get from tb_tickets) Whenever any insert is made on tb_jobs.
ERROR
While creating a trigger I am getting the following error
ERROR #1054 - Unknown column 'program_id' in 'NEW'
tb_tickets
tb_jobs
tb_sites_3
DELIMITER //
CREATE TRIGGER trig_job_color
BEFORE INSERT ON `tb_jobs`
FOR EACH ROW
BEGIN
SET NEW.program_id = (Select program_id from tb_tickets
where tb_tickets.job_id = NEW.job_id);
SET NEW.status = (Select status from tb_tickets
where tb_tickets.job_id = NEW.job_id);
CASE NEW.program_id
WHEN 1 THEN
UPDATE tb_sites_1
SET color_status = NEW.status
WHERE site_id = NEW.site_id;
WHEN 2 THEN
UPDATE tb_sites_2
SET color_status = NEW.status
WHERE site_id = NEW.site_id;
WHEN 3 THEN
UPDATE tb_sites_3
SET color_status = NEW.status
WHERE site_id = NEW.site_id;
END CASE;
END //
DELIMITER ;
Table definations
tb_tickets
CREATE TABLE `tb_tickets` (
`id` int(15) NOT NULL,
`ticket_id` int(15) NOT NULL,
`job_id` int(11) NOT NULL,
`site_id` varchar(200) NOT NULL,
`program_id` int(11) NOT NULL,
`status` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
tb_jobs
CREATE TABLE `tb_jobs` (
`job_id` int(11) NOT NULL AUTO_INCREMENT,
`job_creation` date DEFAULT NULL,
PRIMARY KEY (`job_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
tb_sites_3
CREATE TABLE `tb_sites_3` (
`id` int(15) NOT NULL AUTO_INCREMENT,
`color_status` int(15) NOT NULL,
`site_id` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
CREATE TRIGGER trig_job_color AFTER INSERT ON tb_jobs
FOR EACH ROW BEGIN
SET #program_id = (Select program_id from tb_tickets
where tb_tickets.job_id = NEW.job_id);
SET #newstatus = (Select status from tb_tickets
where tb_tickets.job_id = NEW.job_id);
SET #newsite_id = (Select site_id from tb_tickets
where tb_tickets.job_id = NEW.job_id);
CASE #program_id
WHEN 1 THEN
UPDATE tb_sites_3
SET tb_sites_3.color_status = #newstatus
WHERE tb_sites_3.site_id = #newsite_id;
WHEN 2 THEN
UPDATE tb_sites_3
SET tb_sites_3.color_status = #newstatus
WHERE tb_sites_3.site_id = #newsite_id;
WHEN 3 THEN
UPDATE tb_sites_3
SET tb_sites_3.color_status = #newstatus
WHERE tb_sites_3.site_id = #newsite_id;
END CASE;
END
This worked for me using variables.
DELIMITER //
CREATE TRIGGER trig_job_color
AFTER INSERT ON `tb_jobs`
FOR EACH ROW
BEGIN
DECLARE x, y INT DEFAULT 0;
DECLARE z varchar(50);
SET x = (Select program_id from tb_tickets
where tb_tickets.job_id = NEW.job_id);
SET y = (Select status from tb_tickets
where tb_tickets.job_id = NEW.job_id);
SET Z = (Select site_id from tb_tickets
where tb_tickets.job_id = NEW.job_id);
CASE x
WHEN 1 THEN
UPDATE tb_sites_1
SET color_status = y
WHERE site_id = z;
WHEN 2 THEN
UPDATE tb_sites_2
SET color_status = y
WHERE site_id = z;
WHEN 3 THEN
UPDATE tb_sites_3
SET color_status = y
WHERE site_id = z;
END CASE;
END //
DELIMITER ;

How to fix "Can't update table testtab in stored function/trigger

I have created a table
CREATE TABLE testtab (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` bigint(20) DEFAULT NULL,
`food_id` int(11) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
)
Table contains below row
INSERT INTO testtab (`customer_id`, `food_id`, `created_date`)
VALUES ('433', '9', '2019-05-14 12:00:54');
Now the condition is for a specific customer_id there can be only one row with food_id either 8 or 9.
Now I try to add the below insert statement
INSERT INTO testtab (`customer_id`, `food_id`, `created_date`)
VALUES ('433', '8', '2019-05-14 12:00:54');
Now It should either get failed or get deleted immediately after inserted(record with tag_id=8).I have used the below trigger.But unfortunately i got error
Can't update table 'testtab' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
DELIMITER $$
USE `ipay`$$
DROP TRIGGER /*!50032 IF EXISTS */ `testtabTrigger`$$
CREATE
TRIGGER `testtabTrigger` AFTER INSERT ON `testtab`
FOR EACH ROW BEGIN
IF ((SELECT COUNT(*) FROM testtab WHERE food_id =9 AND customer_id = new.customer_id) =1 && new.food_id = 8) THEN
DELETE FROM testtab WHERE food_id = 8 AND customer_id = new.customer_id;
END IF;
END;
$$
DELIMITER ;
The idea is that you do something like this:
CREATE TRIGGER `testtabTrigger` BEORE INSERT ON `testtab`
FOR EACH ROW
BEGIN
IF (EXISTS (SELECT COUNT(*)
FROM testtab tt
WHERE tt.food_id = 9 AND
tt.customer_id = new.customer_id
) AND
new.food_id = 8
) THEN
signal sqlstate '45000' set message_text = 'Attempted insert of 8 when there is a 9';
END IF;
END;

MySQL handle duplicate key error insert into table with multiple unique indexes; not multi-column unique index

How do I find which unique index has failed from within a stored procedure?
I have created a table with a single column primary key and three single column unique indexes:
CREATE TABLE tableName (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
col1 VARCHAR(50) NOT NULL,
col2 VARCHAR(50) NOT NULL,
col3 VARCHAR(50) NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX id_UNIQUE (id ASC),
UNIQUE INDEX col1_UNIQUE (col1 ASC),
UNIQUE INDEX col2_UNIQUE (col2 ASC),
UNIQUE INDEX col3_UNIQUE (col3 ASC)
) ENGINE = InnoDB;
I have create a stored procedure that handles Error '1062': 'Duplicate entry %s for key %d':
DELIMITER $$
CREATE PROCEDURE insertRecord (
col1Value VARCHAR(50),
col2Value VARCHAR(50),
col3Value VARCHAR(50),
OUT idValue INT,
OUT errColName VARCHAR(50)
) BEGIN
DECLARE EXIT HANDLER FOR 1062 BEGIN
SET errColName = 'Insert Column Name Here';
END;
INSERT tableName SET
col1 = col1Value,
col2 = col2Value,
col3 = col3Value;
SET idValue = LAST_INSERT_ID();
END;
$$
DELIMITER ;
I have called the stored procedure 5 times with different data to return various results:
1st INSERT attempt is successful
-- Initialize parameters
SET #col1Val = 'MySQL',
#col2Val = 'Is',
#col3Val = 'Cool',
#Id = NULL,
#ErrColName = NULL;
-- 1st Insert Attempt
CALL insertRecord(#col1Val, #col2Val, #col3Val, #Id, #ErrColName);
-- Expected result: #Id = 1, #ErrColName = NULL
SELECT #Id '#Id', #ErrColName '#ErrColName';
2nd INSERT Attempt fails because col1 is not unique
-- Re-initialize parameters
SET #col1Val = 'MySQL', -- Intended to generate an error
#col2Val = 'Is',
#col3Val = 'Cool',
#Id = NULL,
#ErrColName = NULL;
-- 2nd Insert Attempt
CALL insertRecord(#col1Val, #col2Val, #col3Val, #Id, #ErrColName);
-- Expected result: #Id = NULL, #ErrColName = 'col1'
SELECT #Id '#Id', #ErrColName '#ErrColName';
3rd INSERT Attempt fails because col2 is not unique
-- Re-initialize parameters
SET #col1Val = 'SQL',
#col2Val = 'Is', -- Intended to generate an error
#col3Val = 'Cool',
#Id = NULL,
#ErrColName = NULL;
-- 3rd Insert Attempt
CALL insertRecord(#col1Val, #col2Val, #col3Val, #Id, #ErrColName);
-- Expected result: #Id = NULL, #ErrColName = 'col2'
SELECT #Id '#Id', #ErrColName '#ErrColName';
4th INSERT Attempt fails because col3 is not unique
-- Re-initialize parameters
SET #col1Val = 'SQL',
#col2Val = 'For',
#col3Val = 'Cool', -- Intended to generate an error
#Id = NULL,
#ErrColName = NULL;
-- 4th Insert Attempt
CALL insertRecord(#col1Val, #col2Val, #col3Val, #Id, #ErrColName);
-- Expected result: #Id = NULL, #ErrColName = 'col3'
SELECT #Id '#Id', #ErrColName '#ErrColName';
5th INSERT Attempt is successful
-- Re-initialize parameters
SET #col1Val = 'SQL',
#col2Val = 'For',
#col3Val = 'Life',
#Id = NULL,
#ErrColName = NULL;
-- 5th Insert Attempt
CALL insertRecord(#col1Val, #col2Val, #col3Val, #Id, #ErrColName);
-- Expected result: #Id = 5, #ErrColName = NULL
SELECT #Id '#Id', #ErrColName '#ErrColName';
What do I need to do in the stored procedure to find which unique index has failed from within a stored procedure?
Thanks in advance.
I found the answer under Which unique key is hit with my insert?. It is not ideal however does solve the problem.
The following is the applied solution:
...
DECLARE EXIT HANDLER FOR 1062 BEGIN
-- Check if col1Value is already in use
IF EXISTS (
SELECT 1
FROM tableName
WHERE col1 = col1value
LIMIT 1
) THEN
SET errColName = 'Col1';
-- Check if col2Value is already in use
ELSEIF EXISTS (
SELECT 1
FROM tableName
WHERE col2 = col2value
LIMIT 1
) THEN
SET errColName = 'Col2';
-- Check if col3Value is already in use
ELSEIF EXISTS (
SELECT 1
FROM tableName
WHERE col3 = col3value
LIMIT 1
) THEN
SET errColName = 'Col3';
END IF;
END;
...

Mysql procedure with no year support

I'm using a MySQL procedure to fetch a shop's open and close times based on two different tables. Normal 'shop_hours' are defined with open/close time and the column day of week (1-7). To allow for customization of normal open/closing times I also have a table named 'shop_hours_special', this is defined with a day of year column.
If I run the argument CALL timesDate('2013-01-02','1', 'false') I get NULL results even though the shop is open this date.
If any MySQL mastermind could give me tips how to make it work with other years than the current, I would be much grateful!
DELIMITER $$
DROP PROCEDURE IF EXISTS timesDate$$
CREATE PROCEDURE timesDate(IN searchedDate DATE, IN dType TINYINT(3), IN ignoreCurrentTime BOOLEAN)
BEGIN
DECLARE final_o_time, final_c_time, o_time, c_time, curTime TIME;
DECLARE dayYear, dayWeek, curDay INT;
DECLARE special_exist BOOLEAN;
SET dayYear = DAYOFYEAR(searchedDate);
SET dayWeek = WEEKDAY(searchedDate) + 1;
SET curDay = DAYOFYEAR(NOW());
SET curTime = TIME(NOW());
SELECT IF(COUNT(*) > 0, TRUE, FALSE), open_time, close_time INTO special_exist, o_time, c_time
FROM shop_hours_special
WHERE day_of_year = dayYear AND `type` = dType;
IF special_exist THEN
IF IgnoreCurrentTime THEN
SET final_o_time = o_time;
SET final_c_time = c_time;
ELSEIF dayYear < curDay THEN
SET final_o_time = NULL;
SET final_c_time = NULL;
ELSEIF dayYear = curDay THEN
IF curTime < o_time THEN
SET final_o_time = o_time;
SET final_c_time = c_time;
ELSEIF curTime < c_time THEN
SET final_o_time = curTime;
SET final_c_time = c_time;
ELSE
SET final_o_time = NULL;
SET final_c_time = NULL;
END IF;
ELSE
SET final_o_time = o_time;
SET final_c_time = c_time;
END IF;
ELSE
SELECT open_time, close_time INTO o_time, c_time
FROM shop_hours
WHERE day_of_week = dayWeek AND (open_time != MAKETIME(0,0,0) OR close_time != MAKETIME(0,0,0)) AND `type` = dType;
IF IgnoreCurrentTime THEN
SET final_o_time = o_time;
SET final_c_time = c_time;
ELSEIF dayYear < curDay THEN
SET final_o_time = NULL;
SET final_c_time = NULL;
ELSEIF dayYear = curDay THEN
IF curTime < o_time THEN
SET final_o_time = o_time;
SET final_c_time = c_time;
ELSEIF curTime < c_time THEN
SET final_o_time = curTime;
SET final_c_time = c_time;
ELSE
SET final_o_time = NULL;
SET final_c_time = NULL;
END IF;
ELSE
SET final_o_time = o_time;
SET final_c_time = c_time;
END IF;
END IF;
SELECT final_o_time, final_c_time;
END$$
DELIMITER ;
MySQL dump:
CREATE TABLE `shop_hours` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`shop_id` int(11) unsigned NOT NULL,
`type` tinyint(3) NOT NULL DEFAULT '1',
`day_of_week` int(11) NOT NULL,
`open_time` time NOT NULL,
`close_time` time NOT NULL,
PRIMARY KEY (`id`),
KEY `shop_id` (`shop_id`),
CONSTRAINT `shop_hours_ibfk_1` FOREIGN KEY (`shop_id`) REFERENCES `shops` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `shop_hours` (`id`, `shop_id`, `type`, `day_of_week`, `open_time`, `close_time`)
VALUES
(1,1,1,1,'09:30:00','20:00:00'),
(2,1,1,2,'09:30:00','20:00:00'),
(3,1,1,3,'09:30:00','20:00:00'),
(4,1,1,4,'09:30:00','20:00:00'),
(5,1,1,5,'09:30:00','20:00:00'),
(6,1,1,6,'11:00:00','20:00:00'),
(7,1,1,7,'11:00:00','20:00:00'),
(8,1,2,1,'11:45:00','12:30:00'),
(9,1,2,2,'11:45:00','12:30:00'),
(10,1,2,3,'11:45:00','12:30:00'),
(11,1,2,4,'11:45:00','12:30:00'),
(12,1,2,5,'11:45:00','12:30:00'),
(13,1,2,6,'00:00:00','00:00:00'),
(14,1,2,7,'00:00:00','00:00:00');
CREATE TABLE `shop_hours_special` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`shop_id` int(11) unsigned NOT NULL,
`type` tinyint(3) NOT NULL DEFAULT '1',
`day_of_year` int(11) NOT NULL,
`open_time` time NOT NULL,
`close_time` time NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`shop_id`,`type`,`day_of_year`),
KEY `shop_id` (`shop_id`),
CONSTRAINT `shop_hours_special_ibfk_1` FOREIGN KEY (`shop_id`) REFERENCES `shops` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `shop_hours_special` (`id`, `shop_id`, `type`, `day_of_year`, `open_time`, `close_time`)
VALUES
(1,1,1,1,'00:00:00','00:00:00'),
(2,1,1,92,'00:00:00','00:00:00'),
(3,1,1,96,'00:00:00','00:00:00'),
(4,1,1,97,'00:00:00','00:00:00'),
(5,1,1,99,'00:00:00','00:00:00'),
(6,1,1,100,'00:00:00','00:00:00'),
(7,1,1,125,'00:00:00','00:00:00'),
(8,1,1,138,'00:00:00','00:00:00'),
(9,1,1,148,'00:00:00','00:00:00'),
(10,1,1,149,'00:00:00','00:00:00'),
(11,1,2,1,'00:00:00','00:00:00'),
(12,1,2,92,'00:00:00','00:00:00'),
(13,1,2,96,'00:00:00','00:00:00'),
(14,1,2,97,'00:00:00','00:00:00'),
(15,1,2,99,'00:00:00','00:00:00'),
(16,1,2,100,'00:00:00','00:00:00'),
(17,1,2,125,'00:00:00','00:00:00'),
(18,1,2,138,'00:00:00','00:00:00'),
(19,1,2,148,'00:00:00','00:00:00'),
(20,1,2,149,'00:00:00','00:00:00'),
(21,1,1,358,'11:00:00','15:00:00'),
(22,1,2,358,'00:00:00','00:00:00'),
(23,1,1,359,'00:00:00','00:00:00'),
(24,1,2,359,'00:00:00','00:00:00'),
(25,1,1,360,'00:00:00','00:00:00'),
(26,1,2,360,'00:00:00','00:00:00'),
(27,1,2,361,'00:00:00','00:00:00'),
(28,1,1,361,'00:00:00','00:00:00'),
(29,1,1,366,'11:00:00','14:00:00'),
(30,1,2,366,'00:00:00','00:00:00'),
(31,1,2,362,'00:00:00','00:00:00'),
(32,1,2,363,'00:00:00','00:00:00');

MYSQL auto_increment_increment

I would like to auto_increment two different tables in a single mysql database, the first by multiples of 1 and the other by 5 is this possible using the auto_increment feature as I seem to only be able to set auto_increment_increment globally.
If auto_increment_increment is not an option what is the best way to replicate this
Updated version: only a single id field is used. This is very probably not atomic, so use inside a transaction if you need concurrency:
http://sqlfiddle.com/#!2/a4ed8/1
CREATE TABLE IF NOT EXISTS person (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY ( id )
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TRIGGER insert_kangaroo_id BEFORE INSERT ON person FOR EACH ROW BEGIN
DECLARE newid INT;
SET newid = (SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'person'
);
IF NEW.id AND NEW.id >= newid THEN
SET newid = NEW.id;
END IF;
SET NEW.id = 5 * CEILING( newid / 5 );
END;
Old, non working "solution" (the before insert trigger can't see the current auto increment value):
http://sqlfiddle.com/#!2/f4f9a/1
CREATE TABLE IF NOT EXISTS person (
secretid INT NOT NULL AUTO_INCREMENT,
id INT NOT NULL,
PRIMARY KEY ( secretid )
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TRIGGER update_kangaroo_id BEFORE UPDATE ON person FOR EACH ROW BEGIN
SET NEW.id = NEW.secretid * 5;
END;
CREATE TRIGGER insert_kangaroo_id BEFORE INSERT ON person FOR EACH ROW BEGIN
SET NEW.id = NEW.secretid * 5; -- NEW.secretid is empty = unusuable!
END;