I have a stored procedure to update some rows in MySQL. But when I call the stored procedure, it affects more than actual rows.
Here is my stored procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `SP_INSERT_DATA`(
IN `incoming_data` TEXT,
IN `value_array` TEXT,
IN `serial_number` VARCHAR(50),
IN `data_timestamp` VARCHAR(50),
OUT `result_id` INT,
OUT `result_message` VARCHAR(500)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE i INT;
DECLARE value_iteration VARCHAR(50);
DECLARE lcl_data_type_id INT;
DECLARE arr_data_type_name VARCHAR(50);
DECLARE affected_data_row_count INT;
DECLARE cstmr_id INT;
DECLARE exit handler FOR 40001
BEGIN
GET DIAGNOSTICS CONDITION 1
#p1 = MYSQL_ERRNO, #p2 = MESSAGE_TEXT;
SET result_id = -2;
SET result_message = CONCAT('RETURNED ERROR NO : ', #p1 , '\r\nMESSAGE TEXT : ',#p2);
ROLLBACK;
END;
DECLARE exit handler for sqlexception
BEGIN
GET DIAGNOSTICS CONDITION 1
#p1 = MYSQL_ERRNO, #p2 = MESSAGE_TEXT;
SET result_id = -999;
SET result_message = CONCAT('RETURNED ERROR NO : ', #p1 , '\r\nMESSAGE TEXT : ',#p2);
ROLLBACK;
END;
START TRANSACTION;
SET i = 1;
SET affected_data_row_count = 0;
SET cstmr_id = 0;
SET result_id = 0;
SET result_message = 'Success';
SELECT id INTO cstmr_id FROM templaricustomers WHERE templaricustomers.customer_serial_number = serial_number LIMIT 1;
IF(cstmr_id <> 0) THEN
WHILE (LOCATE(',', value_array) > 0)
DO
SET arr_data_type_name = SUBSTRING_INDEX(value_array,',',i);
SET value_array = SUBSTRING(value_array, LOCATE(',',value_array) + 1);
SELECT JSON_EXTRACT(incoming_data, arr_data_type_name) INTO value_iteration;
SET arr_data_type_name := SUBSTRING_INDEX(arr_data_type_name, ".", -1);
IF (SELECT COUNT(id) FROM datatypes WHERE datatypes.data_name = arr_data_type_name) > 0 THEN
SELECT id INTO lcl_data_type_id FROM datatypes WHERE datatypes.data_name = arr_data_type_name LIMIT 1;
ELSE
INSERT INTO datatypes (datatypes.data_name,datatypes.description ,datatypes.inserted_date) VALUES(arr_data_type_name,arr_data_type_name,NOW());
SELECT id INTO lcl_data_type_id FROM datatypes WHERE datatypes.data_name = arr_data_type_name LIMIT 1;
END IF;
IF (SELECT COUNT(id) FROM mqttpacket WHERE mqttpacket.data_type_id = lcl_data_type_id AND mqttpacket.customer_id = cstmr_id) > 0 THEN
UPDATE mqttpacket SET mqttpacket.data_value = value_iteration , mqttpacket.inserted_time = data_timestamp WHERE mqttpacket.data_type_id = lcl_data_type_id AND mqttpacket.customer_id = cstmr_id;
ELSE
INSERT INTO mqttpacket (mqttpacket.data_type_id,mqttpacket.customer_id,mqttpacket.data_value,mqttpacket.inserted_time) VALUES(lcl_data_type_id,cstmr_id,value_iteration,data_timestamp);
END IF;
SET affected_data_row_count = affected_data_row_count +1;
END WHILE;
SET result_id = 0;
SET result_message = CONCAT('Query performed successfully. Effected rows : ',CAST(affected_data_row_count AS CHAR));
ELSE
SET result_id = -1;
SET result_message = 'Customer Serial Number not found.';
END IF;
COMMIT;
END
Here is how I call it:
CALL `SP_INSERT_DATA`('{"subcooling":-40,"B1":113,"B2":206,"B3":471,"B4":226,"B5":8,"B6":380,"B7":210,"B8":187,"Discharge":135,"Suction":120,"High_Pressure":90,"Low_Pressure":90,"Evaporation":73,"Condensation":73,"MAX_CMP_SPEED":1100,"Thermal_Limit":748,"SH":46,"EEV_pct":0,"COP":0,"DSH":60,"WaterFlux":8,"FanPower":1,"DeltaTtoStart":0,"DeltaPtoStart":60,"CMP_ROTOR_RPS":0,"SET_CH_FLASH":120,"SET_HP_FLASH":350,"SET_DHW_FLASH":470,"Defrosting":0,"B8_AVERAGE":63,"SET_PLANT":0,"SET_CH_BMS":160,"SET_HP_BMS":200,"SET_DHW_BMS":480,"SET_ACTIVE":200,"SET_DSH":250,"EEV_INJ_pct":0,"LPT":0,"HPT":0,"PLANT_MODE_MANUAL":0,"DHW_MODE_MANUAL":0,"WATER_FLOW":8,"DISCHARGE_TMP":135,"INVERTER_TMP":8,"ENVELOP_ZONE":1,"EEV_A_STEPS":0,"EBM_POWER":1,"EBM_MAX_POWER":106,"COMP_pct_FINAL":0,"TOTAL_POWER_ABSORBED":10,"POWER_OUT_KW":0,"COOLINGCAPACITY":0}' , '$.subcooling,$.B1,$.B2,$.B3,$.B4,$.B5,$.B6,$.B7,$.B8,$.Discharge,$.Suction,$.High_Pressure,$.Low_Pressure,$.Evaporation,$.Condensation,$.MAX_CMP_SPEED,$.Thermal_Limit,$.SH,$.EEV_pct,$.COP,$.DSH,$.WaterFlux,$.FanPower,$.DeltaTtoStart,$.DeltaPtoStart,$.CMP_ROTOR_RPS,$.SET_CH_FLASH,$.SET_HP_FLASH,$.SET_DHW_FLASH,$.Defrosting,$.B8_AVERAGE,$.SET_PLANT,$.SET_CH_BMS,$.SET_HP_BMS,$.SET_DHW_BMS,$.SET_ACTIVE,$.SET_DSH,$.EEV_INJ_pct,$.LPT,$.HPT,$.PLANT_MODE_MANUAL,$.DHW_MODE_MANUAL,$.WATER_FLOW,$.DISCHARGE_TMP,$.INVERTER_TMP,$.ENVELOP_ZONE,$.EEV_A_STEPS,$.EBM_POWER,$.EBM_MAX_POWER,$.COMP_pct_FINAL,$.TOTAL_POWER_ABSORBED,$.POWER_OUT_KW,$.COOLINGCAPACITY,', '123456', '2021-02-24 10:43:00.00' ,#result_id, #result_message);
The table mqttpacket is a system versioned table. Here are the table creation queries.
CREATE TABLE test_database.MQTTPacket(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
data_type_id INT NOT NULL,
customer_id INT NOT NULL,
data_value INT NULL,
row_start TIMESTAMP(6) GENERATED ALWAYS AS ROW START INVISIBLE,
row_end TIMESTAMP(6) GENERATED ALWAYS AS ROW END INVISIBLE,
inserted_time TIMESTAMP(6) NULL DEFAULT NULL,
PERIOD FOR SYSTEM_TIME(row_start,row_end),
FOREIGN KEY (data_type_id) REFERENCES test_database.DataTypes(id),
FOREIGN KEY (customer_id) REFERENCES test_database.templaricustomers(id)
)WITH SYSTEM VERSIONING;
CREATE TABLE `datatypes` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`data_name` VARCHAR(50) NOT NULL COLLATE 'latin1_general_ci',
`inserted_date` DATE NULL DEFAULT NULL,
`description` VARCHAR(50) NULL DEFAULT NULL COLLATE 'latin1_general_ci',
`device_id` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `device_id` (`device_id`) USING BTREE,
CONSTRAINT `datatypes_ibfk_1` FOREIGN KEY (`device_id`) REFERENCES `test_database`.`devices` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
)
CREATE TABLE `templaricustomers` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`customer_serial_number` VARCHAR(50) NOT NULL COLLATE 'latin1_general_ci',
`customer_name` VARCHAR(50) NULL DEFAULT NULL COLLATE 'latin1_general_ci',
`inserted_date` TIMESTAMP(6) NOT NULL DEFAULT current_timestamp(6),
PRIMARY KEY (`id`) USING BTREE
)
So, when I first call the stored procedure, my result_message variable returns "Query performed successfully. Effected rows : 53" however MySql says
Affected rows: 107 Found rows: 0 Warnings: 0 Duration for 1 query: 0.015 sec.
In the second call of the SP, it says
Affected rows: 160 Found rows: 0 Warnings: 0 Duration for 1 query: 0.031 sec.
Thankful for any help in advance.
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');
Below are my table structures and foreign keys:
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='TRADITIONAL';
CREATE SCHEMA IF NOT EXISTS `homework9` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
USE `homework9` ;
-- -----------------------------------------------------
-- Table `homework9`.`employee`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `homework9`.`employee` ;
CREATE TABLE IF NOT EXISTS `homework9`.`employee` (
`EmployeeNumber` INT NOT NULL ,
`FirstName` VARCHAR(15) NULL ,
`LastName` VARCHAR(15) NULL ,
`Department` VARCHAR(15) NULL ,
`Phone` VARCHAR(15) NULL ,
`Email` VARCHAR(25) NULL ,
PRIMARY KEY (`EmployeeNumber`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `homework9`.`computer`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `homework9`.`computer` ;
CREATE TABLE IF NOT EXISTS `homework9`.`computer` (
`SerialNumber` INT NOT NULL ,
`Make` VARCHAR(12) NOT NULL ,
`Model` VARCHAR(24) NOT NULL ,
`ProcessorType` VARCHAR(24) NULL ,
`ProcessorSpeed` DECIMAL(3,2) NOT NULL ,
`MainMemory` VARCHAR(15) NOT NULL ,
`DiskSize` VARCHAR(15) NOT NULL ,
PRIMARY KEY (`SerialNumber`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `homework9`.`computer_assignment`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `homework9`.`computer_assignment` ;
CREATE TABLE IF NOT EXISTS `homework9`.`computer_assignment` (
`EmployeeNumber` INT NOT NULL ,
`SerialNumber` INT NOT NULL ,
`DateAssigned` DATETIME NOT NULL ,
`DateReassigned` DATETIME NULL ,
PRIMARY KEY (`EmployeeNumber`, `SerialNumber`) ,
INDEX `fk_computer_assignment_computer1` (`SerialNumber` ASC) ,
CONSTRAINT `fk_computer_assignment_employee`
FOREIGN KEY (`EmployeeNumber` )
REFERENCES `homework9`.`employee` (`EmployeeNumber` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_computer_assignment_computer1`
FOREIGN KEY (`SerialNumber` )
REFERENCES `homework9`.`computer` (`SerialNumber` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
The updates I'm trying to run causing the error I have...
USE homework9;
set sql_safe_updates=0;
UPDATE employee SET Department = 'marketing' WHERE EmployeeNumber = 9;
UPDATE employee SET phone = '315-999-3344' WHERE LastName = 'rubble';
UPDATE computer SET make = 'Dell', model = 'OptiPlex 980', processortype = 'Intel i3-650',
processorspeed = 3.20, mainmemory = '4.0 GBytyes', DiskSize = '1.0 TBytes'
WHERE SerialNumber = 9871278;
UPDATE computer SET processorspeed = processorspeed + 0.50;
DELETE FROM computer_assignment WHERE EmployeeNumber = 11;
DELETE FROM employee WHERE EmployeeNumber = 11;
DELETE FROM computer_assignment WHERE computer_assignment.EmployeeNumber = employee.EmployeeNumber AND employee.LastName = 'rubble';
set sql_safe_updates=1;
select * from employee;
select * from computer;
select * from computer_assignment;
Result in this error: Unknown column employee.EmployeeNumber in where clause.
What's going on? Any help is greatly appreciated!
DELETE FROM computer_assignment
WHERE computer_assignment.EmployeeNumber = employee.EmployeeNumber
AND employee.LastName = 'rubble';
You haven't mentioned table employee in the FROM clause, so it's unknown.
Maybe you meant
DELETE FROM computer_assignment
WHERE computer_assignment.EmployeeNumber in
(select employee.EmployeeNumber from employee WHERE
employee.LastName = 'rubble')
DELETE FROM computer_assignment
WHERE computer_assignment.EmployeeNumber = employee.EmployeeNumber
AND employee.LastName = 'rubble'
The problem is that employee is not defined anywhere in this query.
DELETE FROM computer_assignment
INNER JOIN employee ON computer_assignment.EmployeeNumber = employee.EmployeeNumber
WHERE computer_assignment.EmployeeNumber = employee.EmployeeNumber
AND employee.LastName = 'rubble'
You're referencing only the computer_assignment table in the FROM so the employee table isn't available here.
DELETE FROM computer_assignment WHERE computer_assignment.EmployeeNumber = employee.EmployeeNumber AND employee.LastName = 'rubble';
Try this:
DELETE FROM computer_assignment WHERE computer_assignment.EmployeeNumber IN (SELECT EmployeeNumber FROM employee WHERE LastName = "Rubble")