error while calling stored procedure: You are using safe update - mysql

I am trying to call a stored procedure, but I am getting : Error Code: 1175 You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
Here is the table:
CREATE TABLE `SystemSetting` (
`SettingName` varchar(45) NOT NULL,
`SettingValue` varchar(45) NOT NULL,
`Deleted` bit(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`SettingName`),
KEY `PK_SystemSetting` (`SettingName`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
and the procedure:
DELIMITER $$
CREATE PROCEDURE `SystemSettingCommit` (IN p_SettingName varchar(45), IN p_SettingValue varchar(45), OUT p_Status varchar(55))
BEGIN
SET p_Status = '00000';
IF (p_SettingValue IS NULL) OR (RTRIM(LTRIM(p_SettingValue)) = '') THEN
SET p_Status = `StatusConcat`(p_Status, '10016');
END IF;
IF (p_SettingName IS NULL) OR (RTRIM(LTRIM(p_SettingName)) = '') THEN
SET p_Status = `StatusConcat`(p_Status, '10017');
END IF;
IF (p_Status = '00000') THEN
IF ((SELECT COUNT(`SettingName`) FROM `SystemSetting` WHERE (`SettingName` = p_SettingName)) > 0) THEN
UPDATE `SystemSetting` SET `SettingValue` = p_SettingValue WHERE (`SettingName` = p_SettingName);
ELSE
INSERT INTO `SystemSetting` (`SettingName`, `SettingValue`) VALUES (p_SettingName, p_SettingValue);
END IF;
END IF;
END$$
DELIMITER;
and this is how I call it:
CALL `SystemSettingCommit` ('Setting1', 'Value1', #Status);

Try this:
SET SQL_SAFE_UPDATES=0;
Or follow this in workbench:
Go to Edit --> Preferences
Click "SQL Queries" tab and uncheck "Safe Updates" check box
Query --> Reconnect to Server
Now execute your sql query

Related

Mysql 5.7 Issue in declare handler for duplicate key

We are facing an issue in declaring handlers in MYSQL 5.7 stored procedure.
Using the documentation present in https://dev.mysql.com/doc/refman/5.7/en/get-diagnostics.html, I'm trying to create handler in my stored procedure to do the following:
If a duplicate key appears, log it and move on insert good row.
End of the stored proc, get me all the error and success rows inserted.
As you can see below, we don't have primary key for table, however have the unique key constraint.
Input
CALL userTableInsert('{"userid":100, "username":"Hello"}, {"userid":102, "username":"World"}, {"userid":102, "username":"World"}', #got_dups)
Expected Output
100:Hello should get inserted and 102:World should get errored out and status needs to be corrected depicted in the output of the stored procedure.
Getting ERR : Error Code: 1064. 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 'DECLARE CONTINUE HANDLER FOR SQLEXCEPTION ...'
Table: user_table
CREATE TABLE `user_table` (
user_id int(20) NOT NULL,
user_name varchar(255) DEFAULT NULL,
created_by varchar(255) NOT NULL,
created_date date NOT NULL,
UNIQUE KEY `user_ukey` (user_id, user_name)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
===============================================
Stored Procedure
===============================================
DELIMITER $$
DROP PROCEDURE IF EXISTS schema.userTableInsert$$
CREATE PROCEDURE schema.userTableInsert(IN JSONArrayParam MEDIUMTEXT, OUT
got_dups INT)
SQL SECURITY INVOKER
BEGIN
DECLARE code CHAR(5) DEFAULT '00000';
DECLARE msg TEXT;
DECLARE rows INT;
DECLARE result TEXT;
DECLARE rowsJSON MEDIUMTEXT DEFAULT NULL;
SET rowsJSON = TRIM(JSONArrayParam);
SET rowsJSON = TRIM(LEADING '[' FROM rowsJSON);
SET rowsJSON = TRIM(TRAILING ']' FROM rowsJSON);
DROP TEMPORARY TABLE IF EXISTS rowsToUse;
CREATE TEMPORARY TABLE rowsToUse (
user_id INT NOT NULL,
user_name VARCHAR(255) DEFAULT NULL
) ENGINE=MEMORY;
WHILE (rowsJSON != '') DO
BEGIN
DECLARE rowJSON VARCHAR(4096) DEFAULT NULL;
DECLARE temp JSON;
DECLARE userid INT DEFAULT NULL;
DECLARE username VARCHAR(255) DEFAULT NULL;
SET rowJSON = CONCAT(SUBSTRING_INDEX(rowsJSON, '}', 1), '}');
SET temp = JSON_EXTRACT(rowJSON, '$.userid');
SET userid = COALESCE(IF(JSON_TYPE(temp) = 'NULL', NULL, REPLACE(temp, '\"', '')));
SET temp = JSON_EXTRACT(rowJSON, '$.username');
SET username = COALESCE(IF(JSON_TYPE(temp) = 'NULL', NULL, REPLACE(temp, '\"', '')));
INSERT INTO rowsToUse(user_id, user_name)
VALUES(userid, username);
IF LOCATE('{', rowsJSON, 2) > 0 THEN
SET rowsJSON = SUBSTRING(rowsJSON, LOCATE('{', rowsJSON, 2));
ELSE
SET rowsJSON = '';
END IF;
END;
END WHILE;
SET SQL_SAFE_UPDATES=0;
# Getting syntax error here
DECLARE CONTINUE HANDLER FOR 1062
BEGIN
GET DIAGNOSTICS CONDITION 1
code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
END;
INSERT INTO user_table(user_id, user_name, created_by , created_date)
SELECT user_id, user_name, 'system', NOW()
FROM rowsToUse;
IF code = '00000' THEN
GET DIAGNOSTICS rows = ROW_COUNT;
SET result = CONCAT('insert succeeded, row count = ',rows);
ELSE
SET result = CONCAT('insert failed, error = ',code,', message = ',msg);
END IF;
DROP TEMPORARY TABLE IF EXISTS rowsToUse;
SET SQL_SAFE_UPDATES=1;
SELECT result;
END
$$
DELIMITER ;
==============================================================
Kindly help me on this.

#1442 - Can't update table ... in stored function/trigger because it is already used by statement which invoked this stored function/trigger

I have this situation:
Two table in two databases:
1st: `persone`.`T_Persone` that contain detailed information about workers plus two fields empty by default: `user_id` and `username`;
2nd: `joomla`.`fe48y_users` that contain information of user in the CMS Joomla including `id` and `username`.
I created a procedure that insert a new user in joomla and return user_id and username of new user created.
I also created also 2 triggers (on update and on insert) that call the procedure and set user_id and username on `T_Persone` table.
I also created a trigger on delete of `joomla`.`fe48y_users` that update `persone`.`T_Persone` and set null to `user_id` and `username` fields.
This is the procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `persone_users_upd`(IN `in_id` INT(10) UNSIGNED, IN `new_email` VARCHAR(255), IN `old_email` VARCHAR(255), OUT `out_user_id` INT(10) UNSIGNED, OUT `out_username` VARCHAR(255))
BEGIN
DECLARE has_email Boolean;
DECLARE my_user_id INT;
DECLARE my_username VARCHAR(255);
DECLARE my_name VARCHAR(255);
SELECT (CASE new_email WHEN '' THEN FALSE ELSE TRUE END) INTO #has_email;
IF #has_email THEN
SELECT CONCAT(`Nome`,' ',`Cognome`), COALESCE(`CF`,LOWER(SUBSTR(new_email, 1, INSTR(new_email, '#') - 1))) INTO #my_name, #my_username FROM `T_Persone` WHERE `IDPersona` = in_id;
IF new_email = old_email THEN
INSERT INTO `spmsf`.`fe48y_users` (`name`, `username`, `email`, `password`, `block`, `sendEmail`, `registerDate`, `lastvisitDate`, `activation`, `params`, `lastResetTime`, `resetCount`, `otpKey`, `otep`, `requireReset`) VALUES
(#my_name, #my_username, new_email, '<omissis>', 0, 1, NOW(), '0000-00-00 00:00:00', '', '{"admin_style":"","admin_language":"","language":"","editor":"","helpsite":"","timezone":"Europe/Rome"}', '0000-00-00 00:00:00', 0, '', '', 0) ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `email` = VALUES(`email`);
ELSE
UPDATE `spmsf`.`fe48y_users` SET `email` = #my_email WHERE `email` = new_email;
END IF;
SELECT `id`, `username` INTO #my_user_id, #my_username FROM `spmsf`.`fe48y_users` WHERE `email` = new_email;
INSERT IGNORE INTO `spmsf`.`fe48y_user_usergroup_map` (`user_id`,`group_id`) VALUES (#my_user_id, 10);
SET out_user_id=#my_user_id, out_username=#my_username;
END IF;
END
these are the triggers on `T_Persone`:
CREATE TRIGGER `persone_del` AFTER DELETE ON `T_Persone`
FOR EACH ROW BEGIN
IF OLD.`user_id` IS NOT NULL THEN
DELETE FROM `spmsf`.`fe48y_users` WHERE `id` = OLD.`user_id`;
DELETE FROM `spmsf`.`fe48y_user_usergroup_map` WHERE `user_id` = OLD.`user_id`;
END IF;
END
CREATE TRIGGER `persone_ins` BEFORE INSERT ON `T_Persone`
FOR EACH ROW BEGIN
CALL persone_users_upd(NEW.`IDPersona`,COALESCE(NEW.`Email`,NEW.`Email_alt`),COALESCE(NEW.`Email`,NEW.`Email_alt`), #user_id, #username);
SET NEW.`user_id` = #user_id, NEW.`username` = #username;
END
CREATE TRIGGER `persone_upd` BEFORE UPDATE ON `T_Persone`
FOR EACH ROW BEGIN
CALL persone_users_upd(NEW.`IDPersona`,COALESCE(NEW.`Email`,NEW.`Email_alt`),COALESCE(OLD.`Email`,OLD.`Email_alt`), #user_id, #username);
SET NEW.`user_id` = #user_id, NEW.`username` = #username;
END
and this is the trigger on `fe48y_users` delete:
CREATE TRIGGER `users_del` BEFORE DELETE ON `fe48y_users`
FOR EACH ROW BEGIN
DECLARE my_user_id Int;
SELECT COUNT(*) INTO #my_user_id FROM `personale`.`T_Persone` WHERE `user_id` = OLD.`id`;
IF #my_user_id > 0 THEN
UPDATE `personale`.`T_Persone` SET `user_id` = NULL, `username` = NULL WHERE `user_id` = OLD.`id`;
END IF;
END
SO, I have two problems:
1st: When I try to delete a user in `fe48y_users` I have the error
#1442 - Can't update table 'fe48y_users' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
2nd: When I insert a new person it don't appear in 'fe48y_users' but when I update it than appear.

Error Code: 1062 Duplicate entry for key 'PRIMARY'

I am constantly getting a Error code 1062: Duplicate Entry.
The first row insert, but then it fails on the same ID.
So everytime I hit execute it will increment: 1466, 1467, 1468, 1469.
And each time there is the same record entered, so I am assuming the autoincrement is only working for the first iteration.
Table:
'entity':
CREATE TABLE `entity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`reg_num` varchar(45) NOT NULL,
`enterprise_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1474 DEFAULT CHARSET=latin1 COMMENT=\'Comment'
Stored procedure:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `tp_to_entityPROC`()
DETERMINISTIC
COMMENT 'stored'
BEGIN
DECLARE done BOOLEAN DEFAULT 0;
DECLARE Tid INT;
DECLARE Tt_name TEXT;
DECLARE allt CURSOR FOR
SELECT training_provider_id, training_provider_name
FROM training_providers;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
OPEN allt;
read_loop: LOOP
IF done THEN
LEAVE read_loop;
END IF;
FETCH allt INTO Tid, Tt_name;
SET #id = 0;
SET #t_name = 0;
SET #id = Tid;
SET #t_name = Tt_name;
SET #empty = '';
if (#id != 0) THEN
INSERT INTO entity (name)
VALUES (#t_name);
SET #my_id = LAST_INSERT_ID();
IF #my_id != 0 THEN
UPDATE training_awarded_providers
SET training_awarded_provider_id = #my_id
WHERE training_awarded_provider_id = #id;
END IF;
END IF;
END LOOP;
CLOSE allt;
END
Not sure about the exact error of duplicate entry but your posted code is not going to work.
Your Table schema
CREATE TABLE `entity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`reg_num` varchar(45) NOT NULL <-- Here it's non null column
In your store procedure you are trying to insert null to reg_num column which will never succeed
if (#id != 0) THEN
INSERT INTO entity (name)
VALUES (#t_name);

TRIGGER MYSQL NOT EXIST

I created this trigger:
CREATE TABLE `Invitations`
( `userId` varchar(255) NOT NULL, `name` varchar(255) DEFAULT NULL,
`status` varchar(1) DEFAULT NULL, `userId_inv` varchar(255) NOT NULL,
PRIMARY KEY (`userId`,`userId_inv`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TRIGGER `Invitation_001_after_trig` AFTER INSERT ON `invitation_001`
FOR EACH ROW
BEGIN
IF ((new.userId,'001') NOT EXISTS (SELECT `userId`,`userId_inv` FROM `Invitations`
WHERE `userId`= new.userId AND `userId_inv` = '001' LIMIT 1))
THEN
INSERT INTO `Invitations`(`userId`, `name`,`status`,`userId_inv`)
values (new.userId, new.name,new.status,'001');
DELETE FROM `invitation_001` WHERE `status` = 'a';
END IF;
END;
It did not work. I had this error:
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 'EXISTS (SELECT userId,userId_inv FROM Invitations WHERE
userId= new.user' at line 1
So could you help me.
I resolved the problem with this trigger:
CREATE TRIGGER `Invitation_001_after_trig` AFTER INSERT ON `invitation_001`
FOR EACH ROW
BEGIN
INSERT INTO `Invitations` (`userId`, `name` ,`status` ,`userId_inv`) SELECT * FROM
invitation_001 iv WHERE
NOT EXISTS (SELECT 1 FROM `Invitations` ivs WHERE ivs.`userId` = iv.`userId` AND
ivs.`userId_inv` = iv.`userId_inv`) AND iv.`userId_inv`='001';END;
Now I've an other issue. I would like to execute a query from a Concat String in a trigger but until now I did not succeed so here is my code:
CREATE TRIGGER `InvitationS_after_trig` AFTER INSERT ON `Invitations`
FOR EACH ROW
BEGIN
if(new.status ='c' OR new.status ='r')
BEGIN
SET #query = CONCAT("INSERT INTO", Invetations.userId,"values(new.userId,new.name,new.status,new.userId_inv);");
PREPARE stmt1 FROM #query;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END IF;
END;
I resolved the syntax problem but I now have an other one:
Dynamic SQL is not allowed in stored function or trigger
I'm using MySQL version 5.1.69.
Finally I give up, I will resolve this problem using java Fonction

MySQL Trigger doesn't know default value

I use this trigger
delimiter ||
create TRIGGER column_a_to_default
BEFORE INSERT ON `property`
FOR EACH ROW
BEGIN
IF NEW.primary_image = '' THEN
SET NEW.primary_image = default(NEW.primary_image);
END IF;
END;
||
delimiter ;
If I insert into the table the trigger throws an error:
Field 'primary_image' doesn't have a default value.
But it does!
What is wrong here? It seems like the trigger isn't aware of default values!
EDIT
Table Create script
CREATE TABLE IF NOT EXISTS `property` (
`id` varchar(10) NOT NULL,
`images` text NOT NULL,
`primary_image` varchar(100) NOT NULL DEFAULT '../no-image.png',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Doesn't default(property.primary_image) work?
(Getting the default of the Real table, not the NEW holding-table)
Somehow it does not work.
Try this workaround -
IF NEW.primary_image = '' THEN
SELECT COLUMN_DEFAULT INTO #def
FROM information_schema.COLUMNS
WHERE
table_schema = 'database_name'
AND table_name = 'property'
AND column_name = 'primary_image';
SET NEW.primary_image = #def;
END IF;