I am trying to create stored procedure and getting error:
Error Code: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right
syntax to use near 'DECLARE #LoopCounter INT DEFAULT 0; DECLARE
#MaxId INT DEFAULT 0; DECLARE ' at line 21
DELIMITER $$
USE dollar$$
DROP PROCEDURE IF EXISTS sp_get_products_google_feed$$
CREATE DEFINER=root#localhost PROCEDURE sp_get_products_google_feed()
BEGIN
DROP TABLE IF EXISTS tmp_Product_List;
CREATE TEMPORARY TABLE tmp_Product_List(
SELECT DISTINCT p.products_id AS PID, p.products_model AS ID, pd.products_name AS Title, pd.products_description AS Description,
'' AS Google_product_category, '' AS product_type, p.products_model AS link, p.products_image AS Image_link,
'new' AS Condition1, 'in stock' AS Availability, p.products_price AS Price, '' AS Sale_Price, '' AS Sale_price_effective_date,
p.products_upc AS GTin, p.manufacturers_id, '' AS MPN, '' AS Item_group_id, '' AS Gender, '' AS Age_group, '' AS Color, '' AS Size,
'Free' AS Shipping, '' AS Shipping_Weight
FROM
zc_products_to_categories pc, zc_products p, zc_products_description pd WHERE
pc.categories_id IN
(SELECT DISTINCT mg.sub_category_id AS id FROM tbl_map_google_category_master mg WHERE mg.category_id = 1
UNION
SELECT DISTINCT mg.sub_sub_category_id AS id FROM tbl_map_google_category_master mg WHERE mg.category_id = 1
ORDER BY id) AND
p.products_id = pc.products_id AND
p.products_id = pd.products_id AND
p.products_status = 1 ORDER BY PID);
DECLARE #LoopCounter INT DEFAULT 0;
DECLARE #MaxId INT DEFAULT 0;
DECLARE #GoogleCategoryid INT DEFAULT 0;
SELECT #LoopCounter = MIN(PID), #MaxId = MAX(PID) FROM tmp_Product_List;
WHILE (#LoopCounter IS NOT NULL AND #LoopCounter <= #MaxId)
BEGIN
SELECT #GoogleCategoryid = google_category_id FROM tbl_map_google_category_master
WHERE
category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = #LoopCounter) OR
sub_category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = #LoopCounter) OR
sub_sub_category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = #LoopCounter) LIMIT 0,1;
UPDATE tmp_Product_List SET Google_product_category = #GoogleCategoryid WHERE products_id = #LoopCounter;
SET #LoopCounter = #LoopCounter + 1
IF(##ROWCOUNT = 0 )
BEGIN
SET #LoopCounter = #LoopCounter + 1
CONTINUE
END
END
SELECT * FROM tmp_Product_List;
END$$
DELIMITER ;
But if I remove below code from script, it run successfully. Trying to find error in full script but no luck.
DECLARE #LoopCounter INT DEFAULT 0;
DECLARE #MaxId INT DEFAULT 0;
DECLARE #GoogleCategoryid INT DEFAULT 0;
SELECT #LoopCounter = MIN(PID), #MaxId = MAX(PID) FROM tmp_Product_List;
WHILE (#LoopCounter IS NOT NULL AND #LoopCounter <= #MaxId)
BEGIN
SELECT #GoogleCategoryid = google_category_id FROM tbl_map_google_category_master
WHERE
category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = #LoopCounter) OR
sub_category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = #LoopCounter) OR
sub_sub_category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = #LoopCounter) LIMIT 0,1;
UPDATE tmp_Product_List SET Google_product_category = #GoogleCategoryid WHERE products_id = #LoopCounter;
SET #LoopCounter = #LoopCounter + 1
IF(##ROWCOUNT = 0 )
BEGIN
SET #LoopCounter = #LoopCounter + 1
CONTINUE
END
END
You had a few issues that I've worked through.
The first is the declaring of the variables with an # sign before them, I've removed those.
The second was in the WHILE ... BEGIN ... END. The syntax is WHILE ... DO ... END WHILE.
The third is a missing semi-colon just before the IF(##ROWCOUNT).
The last one that I haven't fixed below is the use of ##ROWCOUNT. ##ROWCOUNT isn't a variable in MySQL. You can find alternatives here
DELIMITER $$
USE dollar$$
DROP PROCEDURE IF EXISTS sp_get_products_google_feed$$
CREATE DEFINER=root#localhost PROCEDURE sp_get_products_google_feed()
BEGIN
DECLARE LoopCounter INT DEFAULT 0;
DECLARE MaxId INT DEFAULT 0;
DECLARE GoogleCategoryid INT DEFAULT 0;
DROP TABLE IF EXISTS tmp_Product_List;
CREATE TEMPORARY TABLE tmp_Product_List(
SELECT DISTINCT p.products_id AS PID, p.products_model AS ID, pd.products_name AS Title, pd.products_description AS Description,
'' AS Google_product_category, '' AS product_type, p.products_model AS link, p.products_image AS Image_link,
'new' AS Condition1, 'in stock' AS Availability, p.products_price AS Price, '' AS Sale_Price, '' AS Sale_price_effective_date,
p.products_upc AS GTin, p.manufacturers_id, '' AS MPN, '' AS Item_group_id, '' AS Gender, '' AS Age_group, '' AS Color, '' AS Size,
'Free' AS Shipping, '' AS Shipping_Weight
FROM
zc_products_to_categories pc, zc_products p, zc_products_description pd WHERE
pc.categories_id IN
(SELECT DISTINCT mg.sub_category_id AS id FROM tbl_map_google_category_master mg WHERE mg.category_id = 1
UNION
SELECT DISTINCT mg.sub_sub_category_id AS id FROM tbl_map_google_category_master mg WHERE mg.category_id = 1
ORDER BY id) AND
p.products_id = pc.products_id AND
p.products_id = pd.products_id AND
p.products_status = 1 ORDER BY PID);
SELECT LoopCounter = MIN(PID), MaxId = MAX(PID) FROM tmp_Product_List;
WHILE (LoopCounter IS NOT NULL AND LoopCounter <= MaxId)
DO
SELECT GoogleCategoryid = google_category_id FROM tbl_map_google_category_master
WHERE
category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = LoopCounter) OR
sub_category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = LoopCounter) OR
sub_sub_category_id = (SELECT MAX(categories_id) FROM zc_products_to_categories WHERE products_id = LoopCounter) LIMIT 0,1;
UPDATE tmp_Product_List SET Google_product_category = GoogleCategoryid WHERE products_id = LoopCounter;
SET LoopCounter = LoopCounter + 1;
IF(##ROWCOUNT = 0 )
BEGIN
SET LoopCounter = LoopCounter + 1
CONTINUE
END
END WHILE
SELECT * FROM tmp_Product_List;
END$$
DELIMITER ;
I would like to write two While Syntax.
The results I expect are as follows.
when 'H'
tagName1, tagName2, tagname3
when 'D'
tagName1, tagName2, tagname3
when 'M'
tagName1, tagName2, tagname3
when 'Y'
tagName1, tagName2, tagname3
But it didn't worked....
Below is the code that I wrote, while I play it only once.
Any advice, please..
DECLARE tagList varchar(255) DEFAULT 'tagName1,tagName2,tagName3';
DECLARE tagTypeList varchar(150) DEFAULT 'H,D,M,Y';
WHILE tagTypeList != '' DO
WHILE tagList != '' DO
SET tagNameArray = SUBSTRING_INDEX(tagList, ',', 1);
SET tagTypeArray = SUBSTRING_INDEX(tagTypeList, ',', 1);
IF(tagTypeArray = 'H') THEN
SET aDate = (SELECT (DATE_ADD(nDateTime, INTERVAL -1 HOUR)));
SET ago_Y = (SELECT DATE_FORMAT(aDate,'%Y'));
SET ago_M = (SELECT DATE_FORMAT(aDate,'%m'));
SET ago_D = (SELECT DATE_FORMAT(aDate,'%d'));
SET ago_H = (SELECT DATE_FORMAT(aDate,'%H'));
SET ago_W = (SELECT DATE_FORMAT(aDate,'%w'));
ELSEIF(tagTypeArray = 'D') THEN
SET aDate = (SELECT (DATE_ADD(nDateTime, INTERVAL -1 DAY)));
SET ago_Y = (SELECT DATE_FORMAT(aDate,'%Y'));
SET ago_M = (SELECT DATE_FORMAT(aDate,'%m'));
SET ago_D = (SELECT DATE_FORMAT(aDate,'%d'));
SET ago_H = 0;
SET ago_W = 0;
ELSEIF(tagTypeArray = 'M') THEN
SET aDate = (SELECT (DATE_ADD(nDateTime, INTERVAL -1 MONTH)));
SET ago_Y = (SELECT DATE_FORMAT(aDate,'%Y'));
SET ago_M = (SELECT DATE_FORMAT(aDate,'%m'));
SET ago_D = 0;
SET ago_H = 0;
SET ago_W = 0;
ELSEIF(tagTypeArray = 'Y') THEN
SET aDate = (SELECT (DATE_ADD(nDateTime, INTERVAL -1 YEAR)));
SET ago_Y = (SELECT DATE_FORMAT(aDate,'%Y'));
SET ago_M = 0;
SET ago_D = 0;
SET ago_H = 0;
SET ago_W = 0;
END IF;
SET selectValue = (SELECT tagvalue FROM datasource WHERE tagname = tagNameArray and tagtype = tagTypeArray and y=ago_Y and m=ago_M and d=ago_D and h=ago_H);
IF(selectValue IS NULL OR selectValue = '')
THEN
SET old_Value_3M = (Select LastValue from BwAnalogTable where TagName = tagNameArray and LogDate >= ago_3M order by LogDate desc, LogTime desc limit 1);
# Here Insert Querty
END IF;
IF LOCATE(',', tagList) > 0 THEN
SET tagList = SUBSTRING(tagList, LOCATE(',', tagList) + 1);
ELSE
SET tagList = '';
END IF;
END WHILE;
IF LOCATE(',', tagTypeList) > 0 THEN
SET tagTypeList = SUBSTRING(tagTypeList, LOCATE(',', tagTypeList) + 1);
ELSE
SET tagTypeList = '';
END IF;
END WHILE;
I have modified the code as shown below.
DECLARE done INT DEFAULT FALSE;
DECLARE tagType2 VARCHAR(255) DEFAULT '';
DECLARE tagName2 VARCHAR(255) DEFAULT '';
DECLARE tagType_Cur CURSOR for select tagType from tbtagtype;
DECLARE tagName_Cur CURSOR for select tagName from tbtaglist;
OPEN tagType_Cur;
LOOP1: LOOP
FETCH tagType_Cur INTO tagType2;
IF done THEN
CLOSE tagType_Cur;
LEAVE LOOP1;
END IF;
########## here insert your core query ###############
OPEN tagName_Cur;
LOOP2: LOOP
FETCH tagName_Cur INTO tagName2;
IF done THEN
CLOSE tagName_Cur;
SET done = FALSE;
LEAVE LOOP2;
END IF;
########## here insert your core query ###############
END LOOP LOOP2;
END LOOP LOOP1;
I am executing a stored procedure im MYSQL. That will generate 6000 records and insert that 6000 records into a Table. For this, that stored procedure is taking more than 45 min.The file size of stored procedure is 45kb. Systems RAM is 0.98GB.
Does system RAM affecting the stored procedure performance?
CREATE DEFINER=`root`#`localhost` PROCEDURE `sample`()
BEGIN
Declare FY_LHS Varchar(20);
Declare FY_RHS Varchar(20);
Declare abc int default 0;
Declare bcd varchar(40) default null;
Declare cde int default 0;
Declare def varchar(40) default null;
Declare efg int default 0;
Declare ghi varchar(40) default null;
Declare ijk varchar(40) default null;
Declare hij varchar(40) default null;
Declare ijk varchar(40) default null;
Declare param_month int ;
Declare monthsortsequence int default 0;
Declare p int default 0;
Declare q int default 0;
Declare r int default 0;
Declare s int default 0;
Declare t int default 0;
DECLARE done INT DEFAULT FALSE;
declare dateofdisch int default 0;
Declare fId int default 0;
DECLARE fac_cur CURSOR FOR SELECT r FROM u ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET param_month = Month(CURDATE());
IF param_month = 4 THEN SET monthsortsequence = 1;
ELSEIF param_month = 5 THEN SET monthsortsequence = 2;
ELSEIF param_month = 6 THEN SET monthsortsequence = 3;
ELSEIF param_month = 7 THEN SET monthsortsequence = 4;
ELSEIF param_month = 8 THEN SET monthsortsequence = 5;
ELSEIF param_month = 9 THEN SET monthsortsequence = 6;
ELSEIF param_month = 10 THEN SET monthsortsequence = 7;
ELSEIF param_month = 11 THEN SET monthsortsequence = 8;
ELSEIF param_month = 12 THEN SET monthsortsequence = 9;
ELSEIF param_month = 1 THEN SET monthsortsequence = 10;
ELSEIF param_month = 2 THEN SET monthsortsequence = 11;
ELSEIF param_month = 3 THEN SET monthsortsequence = 12;
END IF;
OPEN fac_cur;
read_loop: LOOP
FETCH fac_cur INTO fId;
IF fId >= 65 THEN
LEAVE read_loop;
END IF;
IF fId != 0 THEN
IF MONTH(CURDATE())>=4 THEN
Set FY_LHS = YEAR(CURDATE());
Set FY_RHS = YEAR(CURDATE())+1;
ELSE
Set FY_LHS = YEAR(CURDATE())-1;
Set FY_RHS = YEAR(CURDATE());
END IF;
Select tblbc.StateId, tblst.StateName, tblbc.DistrictId,
tblst.District, tblbc.kID, tblst.k, tblbc.FacilityName, tblbc.FacilityType,
tblbc.ReportingToId
into abc, bcd, cde, def, efg, ghi, ijk, hij, ijk
from u tblbc inner join tblstateinfo tblst on
tblbc.stateid = tblst.stateid and tblbc.DistrictId = tblst.dcode and tblbc.kID = tblst.tcode
where tblbc.r = fId;
Delete from data where Year = concat(FY_LHS,'-',FY_RHS) and Month = param_month and r = fId;
Set p = (select count(*) as Count from w tblreg inner join tblp1s tblu on tblreg.p1id = tblu.p1id where tblreg.pm = 0 and (Str_To_Date(tblreg.ty, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(tblreg.ty, '%d/%m/%Y')) = param_month and tblu.r = fId);
Set q = (Select count(ytid) as Count From w reg inner join tblp1s tblu on reg.p1id = tblu.p1Id where datediff(CurDate(), Str_To_Date(reg.LMP, '%d/%m/%Y')) < 300 and reg.pm = 0 and (Str_To_Date(reg.ty, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(reg.ty, '%d/%m/%Y')) = param_month and tblu.r = fId);
Set r = (Select count(reg.ytid) from (Select ts.p1id, ts.ytid, count(ts.ytid) as count from tblhjlist ts where ts.fgtype = 'ANC' and ts.actualdateofaction is not null and (Str_To_Date(actualdateofaction, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(actualdateofaction, '%d/%m/%Y')) = param_month group by ts.ytid, ts.p1id) tss left join w reg on tss.ytid = reg.ytid inner join tblp1s tblu on reg.p1Id = tblu.p1id where tss.count = 3 and tblu.r = fId);
Set s = (Select count(sl.ytid) from (Select p1id, ytid from tblhjlist where fgid = 1 and fgtype = 'FT' and actualdateofaction is not null and (Str_To_Date(actualdateofaction, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(actualdateofaction, '%d/%m/%Y')) = param_month) sl inner join w reg on sl.ytid = reg.ytid inner join tblp1s tblu on reg.p1id = tblu.p1id and reg.pm = 0 and tblu.r = fId);
Set t = (Select count(ts.ytid) from (Select p1id, ytid from tblhjlist where ((fgtype = 'FT' and fgid = 2) or (fgtype = 'FTBooster' and fgid = 3)) and actualdateofaction is not null and (Str_To_Date(actualdateofaction, '%d/%m/%Y') between Str_To_Date(concat(FY_LHS,'/04/01'), '%Y/%m/%d') and Str_To_Date(concat(FY_RHS,'/03/31'), '%Y/%m/%d')) and month(Str_To_Date(actualdateofaction, '%d/%m/%Y')) = 9 group by ytid) ts inner join w reg on ts.ytid = reg.ytid inner join tblp1s tblu on reg.p1Id = tblu.p1Id and reg.pm = 0 and tblu.r = fId);
.
.
.
.
.
40 queries
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 2, '1.1.1', q, ijk);
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 1, '1.1', p, ijk);
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 3, '1.3', r, ijk);
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 4, '1.4.1', s, ijk);
insert into data (year, month, stateId, state, districtId, district, kid, k, facilityname, facilityType, sortsequenceMonth, r, sortsequence, itemRefno, itemvalue, ReportingToId) values (concat(FY_LHS,'-',FY_RHS), param_month, abc, bcd, cde, def, efg, ghi, ijk, hij, monthsortsequence, fId, 5, '1.4.2', t, ijk);
.
.
.
.
40 insert statements
set fId = fId + 1;
END IF;
END LOOP;
CLOSE fac_cur;
END
You need to check which statement exactly in the stored procedure
is taking time by adding some debug points (ex: You can insert
timestamp after each select into some temp table).
You need to check that you have proper indexes on table for select
queries.
guys!
I have a trigger in MySQL database:
CREATE DEFINER="root"#"127.0.0.1" TRIGGER `tai_actions_for_active_count` AFTER INSERT ON `actions` FOR EACH ROW BEGIN
DECLARE l_isnn TINYTEXT;
IF NEW.action_type IN ('CREATION', 'VERIFICATION', 'CLOSE') THEN
SET l_isnn = IF(NEW.isnn is NULL, '*', NEW.isnn);
IF NOT NEW.action_type = 'CLOSE' THEN
INSERT INTO subscriptions.`statistics_active_count`(`service_id`, `operator_id`, `isnn`, `active_count`)
VALUES (NEW.service_id, NEW.operator_id, l_isnn, 1)
ON DUPLICATE KEY UPDATE active_count = active_count + 1;
ELSE
SET #tai_actions_for_active_count = -1;
UPDATE subscriptions.`statistics_active_count` SET active_count = #tai_actions_for_active_count := active_count - 1
WHERE `service_id` = NEW.service_id AND `operator_id` = NEW.operator_id AND `isnn` = l_isnn;
IF #tai_actions_for_active_count = 0 THEN DELETE FROM subscriptions.`statistics_active_count` WHERE `active_count` = 0; END IF;
END IF;
END IF;
END
So I need to rewrite it to make it works in Postgres database. As there's ON DUPLICATE KEY UPDATE I'm using Postgres version 9.5 with UPSERT (ON CONFLICT (KEY) DO UPDATE).
So I poorly know SQL language can you tell me what I'm doing wrong? There's the Postgres PL code:
DECLARE
l_isnn TEXT;
tai_actions_for_active_count INTEGER;
BEGIN
IF NEW.action_type IN ('CREATION', 'VERIFICATION', 'CLOSE') THEN
IF NEW.isnn is NULL THEN
l_isnn := '*';
ELSE
l_isnn := NEW.isnn;
END IF;
IF NOT NEW.action_type = 'CLOSE' THEN
INSERT INTO "subscriptions.statistics_active_count"(service_id, operator_id, isnn, active_count)
VALUES (NEW.service_id, NEW.operator_id, l_isnn, 1)
ON CONFLICT(active_count) DO UPDATE SET active_count = active_count + 1;
ELSE
tai_actions_for_active_count := -1;
UPDATE "subscriptions.statistics_active_count" SET active_count = active_count - 1
-- (tai_actions_for_active_count := active_count - 1)
WHERE service_id = NEW.service_id AND operator_id = NEW.operator_id AND isnn = l_isnn;
UPDATE "subscriptions.statistics_active_count" SET tai_actions_for_active_count = active_count
WHERE service_id = NEW.service_id AND operator_id = NEW.operator_id AND isnn = l_isnn;
IF tai_actions_for_active_count = 0 THEN DELETE FROM "subscriptions.statistics_active_count" WHERE active_count = 0; END IF;
END IF;
END IF;
RETURN NULL;
END;
As I want to test this trigger I'm getting an error -- relation "subscriptions.statistics_active_count" does not exist
Can you help me with that code?
Finally I've got the solution. I guess :)
BEGIN
IF NEW.action_type IN ('CREATION', 'VERIFICATION', 'CLOSE') THEN
IF NEW.isnn IS NULL THEN
l_isnn := '*';
ELSE
l_isnn := NEW.isnn;
END IF;
IF NOT NEW.action_type = 'CLOSE' THEN
BEGIN
INSERT INTO subscriptions.statistics_active_count (service_id, operator_id, isnn, active_count)
VALUES (NEW.service_id, NEW.operator_id, l_isnn, 1);
EXCEPTION WHEN unique_violation THEN
UPDATE subscriptions.statistics_active_count SET active_count = active_count + 1
WHERE service_id = NEW.service_id and operator_id=NEW.operator_id;
END;
ELSE
tai_actions_for_active_count := -1;
WITH upd AS
(UPDATE subscriptions.statistics_active_count
SET active_count = active_count - 1
WHERE service_id = NEW.service_id AND operator_id = NEW.operator_id AND isnn = l_isnn;
RETURNING active_count)
SELECT *
FROM upd INTO tai_actions_for_active_count;
IF tai_actions_for_active_count = 0 THEN
DELETE FROM public.statistics_active_count
WHERE active_count = 0;
END IF;
END IF;
END IF;
END;