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;