Mysql procedure with no year support - mysql
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');
Related
MySQL stored procedure returns more than one row
So I've created this stored procedure, where I made a check if the row with the values already exists or not, before implementing a new row to the database. If the row already exists, I return the existing ID of that row, else I return the newly created row ID. The Stored procedure is: BEGIN DECLARE TestJobExists int; SELECT id into TestJobExists FROM TestJob WHERE `JobLink` = JobLink AND `StartTime` = StartTime AND `Endtime` = Endtime AND `Owner` = Owner_info AND `Engine` = Engine_info AND (`TestSuiteId` = TestSuiteId or `TestSuiteId` is NULL) AND (`TestSuiteCollectionId` = TestSuiteCollectionId or `TestSuiteCollectionId` is NULL) AND `Finished` = Finished AND `JenkinsBuild` = JenkinsBuild AND `JenkinsJobName` = JenkinsJobName; -- Set values to NULL if we have an empty string (we allow either null or ints) IF TestSuiteId = '' THEN SET TestSuiteId = null; END IF; IF TestSuiteCollectionId = '' THEN SET TestSuiteCollectionId = null; END IF; IF TestSuiteCollectionId != '' THEN SET TestSuiteId = null; END IF; -- If we have found an ID it should be above or equal to 1 else insert new row IF TestJobExists >= 1 THEN SELECT TestJobExists AS LastInsertId; ELSE INSERT INTO TestJob (`id`,`JobLink`,`StartTime`,`Endtime`,`Owner`,`Engine`,`TestSuiteId`,`TestSuiteCollectionId`,`Finished`,`JenkinsBuild`,`JenkinsJobName`) VALUES (NULL, JobLink, StartTime, Endtime, Owner_info, Engine_info, TestSuiteId, TestSuiteCollectionId, Finished, JenkinsBuild, JenkinsJobName); SELECT LAST_INSERT_ID() AS LastInsertId; END IF; END TestJobExists will be set to the existing ID or null if it doesn't exist. If it doesn't exist we insert a new row. I tried to run the SQL query, which only returned a single row: SELECT id into TestJobExists FROM TestJob WHERE `JobLink` = "https://www.test.com" AND `StartTime` = "2022-05-02 08:36:07" AND `Endtime` = "2022-05-02 09:24:23" AND `Owner` = "" AND `Engine` = "Tap" AND (`TestSuiteId` = "" or `TestSuiteId` is NULL) AND (`TestSuiteCollectionId` = "462" or `TestSuiteCollectionId` is NULL) AND `Finished` = "SUCCESS" AND `JenkinsBuild` = "537" AND `JenkinsJobName` = "VTU"; But when I call the stored procedure with exactly the same values it says that it cant return more than one row: CALL CreateTestJob("https://www.test.com","2022-05-02 08:36:07","2022-05-02 09:24:23","","Tap","","462","SUCCESS","537","VTU") So why does it return a single row when I run it for itself and why does it return multiple when it's inside the stored procedure? My guess is that it's something to do with my understanding on how either this is used (TestSuiteId = "" or TestSuiteId is NULL) AND (TestSuiteCollectionId = "462" or TestSuiteCollectionId is NULL) or the way the SQL searches for the DATETIME rows StartTime = "2022-05-02 08:36:07" AND Endtime = "2022-05-02 09:24:23" This is how the table looks: Table: testjob Columns: id int(11) AI PK Timestamp timestamp JobLink varchar(300) JobNo int(11) StartTime datetime EndTime datetime Owner varchar(45) Engine varchar(100) TestSuiteId int(11) TestSuiteCollectionId int(11) Finished varchar(45) JenkinsBuild int(100) JenkinsJobName varchar(100) LogTimestamp varchar(45) JobVerdict varchar(45) logText longtext FlagStatus int(11) Delete int(11) Manuel int(11)
MySQL SELECT not finding known values
There is probably something simple here that I'm just not seeing, but I've been trying all I can think of for a few hours. It's time to toss it to more knowledgable folks... I want to attempt to intercept a duplicate index, so my auto increment value doesn't advance. Plus, after this much time, it has just become one of those things I have to solve at this point. Starting with an empty table, I call the procedure with PricingHeaderID_In set to zero in order to invoke the INSERT logic. Lookup1 obviously finds nothing, because there is nothing to find, and pricingHeaderID1 is NULL. Then, the new row is inserted, Lookup2 retrieves the newly inserted row as expected, and pricingHeaderID2 shows the correct value. Now, I call the procedure with EXACTLY the same values everywhere, Lookup1 still finds nothing, and pricingHeaderID1 is NULL. That causes the insert logic to run, and MySQL correctly detects a duplicate. My question is simple: If MySQL can detect that the values will cause a duplicate key, then why is Lookup1 failing? Here's my table definition: CREATE TABLE PricingHeaders ( PricingHeaderID bigint NOT NULL AUTO_INCREMENT, UserID bigint NOT NULL, ClientName varchar(100) NOT NULL, Subdivision varchar(100) NOT NULL, SubjectProperty varchar(100) NOT NULL, DatePrepared date NOT NULL, MonthsSearched smallint DEFAULT NULL, Bedrooms tinyint DEFAULT NULL, Bathrooms tinyint DEFAULT NULL, Stories tinyint DEFAULT NULL, SquareFeet smallint DEFAULT NULL, YearBuilt smallint DEFAULT NULL, HasPool bit DEFAULT 0, Created datetime DEFAULT CURRENT_TIMESTAMP, Modified datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (PricingHeaderID), UNIQUE KEY UserClientPropertyDate (UserID,ClientName,SubjectProperty,DatePrepared), INDEX UserSubdivision (UserID,Subdivision) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci; And here's my stored procedure: CREATE PROCEDURE SavePricingHeader ( Token_In VARCHAR(36), PricingHeaderID_In bigint, UserID_In bigint, ClientName_In varchar(100), Subdivision_In varchar(100), SubjectProperty_In varchar(100), DatePrepared_In date, MonthsSearched_In smallint, Bedrooms_In tinyint, Bathrooms_In tinyint, Stories_In tinyint, SquareFeet_In smallint, YearBuilt_In smallint, HasPool_In bit ) BEGIN DECLARE errNo int DEFAULT 0; DECLARE errMsg varchar(250) DEFAULT 'OK'; DECLARE currOp varchar(250) DEFAULT 'Init'; DECLARE pricingHeaderID1 bigint DEFAULT NULL; DECLARE pricingHeaderID2 bigint DEFAULT NULL; DECLARE tokenValidated bit DEFAULT 0; DECLARE sqlErrNo CHAR(5) DEFAULT '00000'; DECLARE sqlErrMsg TEXT DEFAULT ''; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN GET DIAGNOSTICS CONDITION 1 sqlErrNo = RETURNED_SQLSTATE, sqlErrMsg = MESSAGE_TEXT; SET errNo = 1; SET errMsg = 'SQL Error'; END; IF errNo = 0 THEN SET currOp = 'Extend session'; CALL ExtendSession(Token_In, tokenValidated); END IF; IF errNo = 0 THEN IF tokenValidated = 0 THEN SET errNo = 9001; SET errMsg = 'Invalid session.'; END IF; END IF; IF errNo = 0 THEN SET currOp = 'Lookup1'; SELECT `PricingHeaderID` INTO pricingHeaderID1 FROM `PricingHeaders` WHERE `UserID` = UserID_In AND `ClientName` = ClientName_In AND `SubjectProperty` = SubjectProperty_In AND `DatePrepared` = DatePrepared_In; IF errNo = 0 THEN IF pricingHeaderID1 IS NOT NULL THEN IF pricingHeaderID1 <> PricingHeaderID_In THEN SET errNo = 9002; SET errMsg = 'Duplicate Index.'; END IF; END IF; END IF; END IF; IF errNo = 0 THEN IF PricingHeaderID_In = 0 THEN SET currOp = 'Insert'; INSERT INTO `PricingHeaders` ( `UserID`, `ClientName`, `Subdivision`, `SubjectProperty`, `DatePrepared`, `MonthsSearched`, `Bedrooms`, `Bathrooms`, `Stories`, `SquareFeet`, `YearBuilt`, `HasPool` ) VALUES ( UserID_In, ClientName_In, Subdivision_In, SubjectProperty_In, DatePrepared_In, MonthsSearched_In, Bedrooms_In, Bathrooms_In, Stories_In, SquareFeet_In, YearBuilt_In, HasPool_In ); IF errNo = 0 THEN SET pricingHeaderID1 = LAST_INSERT_ID(); END IF; ELSE SET currOp = 'Update'; SET pricingHeaderID1 = PricingHeaderID_In; UPDATE `PricingHeaders` SET `ClientName` = ClientName_In, `Subdivision` = Subdivision_In, `SubjectProperty` = SubjectProperty_In, `DatePrepared` = DatePrepared_In, `MonthsSearched` = MonthsSearched_In, `Bedrooms` = Bedrooms_In, `Bathrooms` = Bathrooms_In, `Stories` = Stories_In, `SquareFeet` = SquareFeet_In, `YearBuilt` = YearBuilt_In, `HasPool` = HasPool_In WHERE `PricingHeaderID` = PricingHeaderID_In; END IF; END IF; IF errNo = 0 THEN SET currOp = 'Lookup2'; SELECT `PricingHeaderID` INTO pricingHeaderID2 FROM `PricingHeaders` WHERE `UserID` = UserID_In AND `ClientName` = ClientName_In AND `SubjectProperty` = SubjectProperty_In AND `DatePrepared` = DatePrepared_In; END IF; IF errNo = 0 THEN IF pricingHeaderID2 IS NULL THEN SET errNo = 9003; SET errMsg = 'Not retrieved.'; END IF; END IF; SELECT pricingHeaderID1, pricingHeaderID2, errNo, errMsg, currOp, sqlErrNo, sqlErrMsg; END
Your basic problem is your call to the second procedure, which must look like CALL ExtendSession(Token_In, #tokenValidated) Whe4n you want to retrieve an OUT variable in MySQL# CREATE TABLE PricingHeaders ( PricingHeaderID bigint NOT NULL AUTO_INCREMENT, UserID bigint NOT NULL, ClientName varchar(100) NOT NULL, Subdivision varchar(100) NOT NULL, SubjectProperty varchar(100) NOT NULL, DatePrepared date NOT NULL, MonthsSearched smallint DEFAULT NULL, Bedrooms tinyint DEFAULT NULL, Bathrooms tinyint DEFAULT NULL, Stories tinyint DEFAULT NULL, SquareFeet smallint DEFAULT NULL, YearBuilt smallint DEFAULT NULL, HasPool bit DEFAULT 0, Created datetime DEFAULT CURRENT_TIMESTAMP, Modified datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (PricingHeaderID), UNIQUE KEY UserClientPropertyDate (UserID,ClientName,SubjectProperty,DatePrepared), INDEX UserSubdivision (UserID,Subdivision) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci; CREATE PROCEDURE ExtendSession(IN Token_In VARCHAR(36), OUT tokenValidated int) BEGIN SET tokenValidated = 1; END; ✓ CREATE PROCEDURE SavePricingHeader ( Token_In VARCHAR(36), PricingHeaderID_In bigint, UserID_In bigint, ClientName_In varchar(100), Subdivision_In varchar(100), SubjectProperty_In varchar(100), DatePrepared_In date, MonthsSearched_In smallint, Bedrooms_In tinyint, Bathrooms_In tinyint, Stories_In tinyint, SquareFeet_In smallint, YearBuilt_In smallint, HasPool_In bit ) BEGIN DECLARE errNo int DEFAULT 0; DECLARE errMsg varchar(250) DEFAULT 'OK'; DECLARE currOp varchar(250) DEFAULT 'Init'; DECLARE pricingHeaderID1 bigint DEFAULT NULL; DECLARE pricingHeaderID2 bigint DEFAULT NULL; DECLARE tokenValidated bit DEFAULT 0; DECLARE sqlErrNo CHAR(5) DEFAULT '00000'; DECLARE sqlErrMsg TEXT DEFAULT ''; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN GET DIAGNOSTICS CONDITION 1 sqlErrNo = RETURNED_SQLSTATE, sqlErrMsg = MESSAGE_TEXT; SET errNo = 1; SET errMsg = 'SQL Error'; END; IF errNo = 0 THEN SET currOp = 'Extend session'; CALL ExtendSession(Token_In, #tokenValidated); END IF; IF errNo = 0 THEN IF #tokenValidated = 0 THEN SET errNo = 9001; SET errMsg = 'Invalid session.'; END IF; END IF; IF errNo = 0 THEN SET currOp = 'Lookup1'; SELECT `PricingHeaderID` INTO pricingHeaderID1 FROM `PricingHeaders` WHERE `UserID` = UserID_In AND `ClientName` = ClientName_In AND `SubjectProperty` = SubjectProperty_In AND `DatePrepared` = DatePrepared_In; IF errNo = 0 THEN IF pricingHeaderID1 IS NOT NULL THEN IF pricingHeaderID1 <> PricingHeaderID_In THEN SET errNo = 9002; SET errMsg = 'Duplicate Index.'; END IF; END IF; END IF; END IF; IF errNo = 0 THEN IF PricingHeaderID_In = 0 THEN SET currOp = 'Insert'; INSERT INTO `PricingHeaders` ( `UserID`, `ClientName`, `Subdivision`, `SubjectProperty`, `DatePrepared`, `MonthsSearched`, `Bedrooms`, `Bathrooms`, `Stories`, `SquareFeet`, `YearBuilt`, `HasPool` ) VALUES ( UserID_In, ClientName_In, Subdivision_In, SubjectProperty_In, DatePrepared_In, MonthsSearched_In, Bedrooms_In, Bathrooms_In, Stories_In, SquareFeet_In, YearBuilt_In, HasPool_In ); IF errNo = 0 THEN SET pricingHeaderID1 = LAST_INSERT_ID(); END IF; ELSE SET currOp = 'Update'; SET pricingHeaderID1 = PricingHeaderID_In; UPDATE `PricingHeaders` SET `ClientName` = ClientName_In, `Subdivision` = Subdivision_In, `SubjectProperty` = SubjectProperty_In, `DatePrepared` = DatePrepared_In, `MonthsSearched` = MonthsSearched_In, `Bedrooms` = Bedrooms_In, `Bathrooms` = Bathrooms_In, `Stories` = Stories_In, `SquareFeet` = SquareFeet_In, `YearBuilt` = YearBuilt_In, `HasPool` = HasPool_In WHERE `PricingHeaderID` = PricingHeaderID_In; END IF; END IF; IF errNo = 0 THEN SET currOp = 'Lookup2'; SELECT `PricingHeaderID` INTO pricingHeaderID2 FROM `PricingHeaders` WHERE `UserID` = UserID_In AND `ClientName` = ClientName_In AND `SubjectProperty` = SubjectProperty_In AND `DatePrepared` = DatePrepared_In; END IF; IF errNo = 0 THEN IF pricingHeaderID2 IS NULL THEN SET errNo = 9003; SET errMsg = 'Not retrieved.'; END IF; END IF; SELECT pricingHeaderID1, pricingHeaderID2, errNo, errMsg, currOp, sqlErrNo, sqlErrMsg; END ✓ CALL SavePricingHeader(1,0,1,'test','subd','subepro',NOW(), 1,2,1,1,12,1981,0) pricingHeaderID1 | pricingHeaderID2 | errNo | errMsg | currOp | sqlErrNo | sqlErrMsg ---------------: | ---------------: | ----: | :----- | :------ | :------- | :-------- 1 | 1 | 0 | OK | Lookup2 | 00000 | ✓ db<>fiddle here
Stored Procedure Updating more than one time MySQL
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.
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 ;
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);