Select statement inside a loop in a Mysql Stored Procedure - mysql

Can we use Select statement inside a loop in a Mysql Stored Procedure?
why is the code wrong
create procedure AbsentReportproc (INOUT fromdate DATETIME, INOUT todate DATETIME)
as
begin
DECLARE startdate DATE;
DECLARE enddate DATE;
DECLARE nofdays INT;
DECLARE counter INT;
DECLARE countdate DATE;
startdate=fromdate;
enddate=todate;
countdate=fromdate;
nofdays=DATEDIFF(DAY,startdate,endate);
counter=1;
while counter<=noofdays
loop
select CARDNO from test_prefixmaster
where CARDNO not in ( select CARDNO from test_prefixtransactions where Date(S_DateTime)=countdate)
set countdate=countdate+1;
set counter=counter+1;
end loop;
end//

Try this:
DELIMITER $$
DROP PROCEDURE IF EXISTS `AbsentReportproc`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `AbsentReportproc`(IN _fromdate DATETIME, IN _todate DATETIME)
BEGIN
CREATE TEMPORARY TABLE daterange (dte DATE);
SET #counter := -1;
WHILE (#counter < DATEDIFF(DATE(_todate), DATE(_fromdate))) DO
INSERT daterange VALUES (DATE_ADD(_fromdate, INTERVAL #counter:=#counter + 1 DAY));
END WHILE;
SELECT tp.cardno, tp.EMPCODE, tp.DEPARTMENT, GROUP_CONCAT(d.dte) Absentddate, COUNT(tp.cardno) Totalnoofabsentdates
FROM test_prefixmaster tp JOIN daterange d
LEFT JOIN test_prefixtransactions tpt ON tp.cardno = tpt.CARDNO AND DATE(S_DateTime) = d.dte
WHERE tpt.CARDNO IS NULL
GROUP BY tp.cardno;
DROP TABLE daterange;
END$$
DELIMITER ;

You didn't need a loop for this. You can do so:
SELECT
p.CARDNO,
COUNT(CARDNO) AS countdate
FROM test_prefixmaster p
INNER JOIN test_prefixtransactions t ON p.CARDNO = t.CARDNO
WHERE Date(t.S_DateTime) BETWEEN fromdate
AND todate
GROUP BY p.CARDNO;

Related

anyone help me out here why getting error in my store procedure

i am trying to insert all date in daterange table within specific given date rane.here is my procedure but i am getting error and i can't solve it.
DELIMITER//
CREATE PROCEDURE example(IN sdate DATE, IN enddate DATE)
BEGIN
SET #sdate = sdate;
SET #enddate=enddate;
WHILE(#sdate < #enddate) DO
INSERT INTO daterange SET day = sdate;
sdate = DATE_ADD(sdate, INTERVAL 1 DAY);
END WHILE;
SELECT * FROM daterange;
END//;
DELIMITER ;
Try enter space into Delimiter and //
And your while have syntax erros, look at the fix procedure:
DELIMITER //
CREATE PROCEDURE example(IN sdate DATE, IN enddate DATE)
BEGIN
declare varDay date;
WHILE(sdate < enddate) DO
INSERT INTO daterange ([your-column]) values (varDay);
SET sdate = DATE_ADD(sdate, INTERVAL 1 DAY);
SET varDay = sdate;
END WHILE;
SELECT * FROM daterange;
END //;
DELIMITER ;

MySQL Stored Procedure Delimiter

I try to create following procedure:
DROP PROCEDURE IF EXISTS my_super_procedure;
DELIMITER $$
CREATE PROCEDURE my_super_procedure(IN in_id VARCHAR(255), IN in_from_date timestamp, IN in_to_date timestamp)
BEGIN
DROP TEMPORARY TABLE IF EXISTS tblResults;
CREATE TEMPORARY TABLE IF NOT EXISTS tblResults(
selected_date timestamp,
total_value int
); -- !!!!! Syntax error: missing END
DECLARE tmp_date timestamp;
SET tmp_date = in_from_date;
WHILE tmp_date < in_to_date DO
SELECT count(*) as total_events FROM event e where e.scheduled between tmp_date and tmp_date + interval 1 day;
set tmp_date = DATE_ADD(tmp_date, INTERVAL 1 DAY);
END WHILE;
END$$
DELIMITER ;
call my_super_procedure("3dccd75a-4c8e-11e7-bf68-5ce0c56861d1", "2017-06-24 04:16:43", "2017-06-28 04:16:43");
I'm new in stored procedures.
How can I fix this error?
Declare all variables at the beginning, not in the middle of your code.
DROP PROCEDURE IF EXISTS my_super_procedure;
DELIMITER $$
CREATE PROCEDURE my_super_procedure(IN in_id VARCHAR(255), IN in_from_date timestamp, IN in_to_date timestamp)
BEGIN
DECLARE tmp_date timestamp;
DROP TEMPORARY TABLE IF EXISTS tblResults;
CREATE TEMPORARY TABLE IF NOT EXISTS tblResults(
selected_date timestamp,
total_value int
);
SET tmp_date = in_from_date;
WHILE tmp_date < in_to_date DO
SELECT count(*) as total_events FROM event e where e.scheduled between tmp_date and tmp_date + interval 1 day;
set tmp_date = DATE_ADD(tmp_date, INTERVAL 1 DAY);
END WHILE;
END$$
DELIMITER ;

error shown call mysql stored procedure in query browser

I have created a stored procedure in mysql. When I call the procedure in mysql query browser it shows error "procedure dose not exist" but I am sure that the stored procedure exists in the database.I don't know where I am going wrong. Please help anyone
This is my Stored Procedure Code
DELIMITER $$
DROP PROCEDURE IF EXISTS `aad_adr`.` MonthlySalesReport(IN fromdate DATE,IN todate DATE)` $$
CREATE PROCEDURE `aad_adr`.` MonthlySalesReport(IN fromdate DATE,IN todate DATE)` ()
BEGIN
Declare fd DATE;
Declare ed DATE;
SET fd=fromdate;
SET ed=todate;
WHILE DATE(fd)<=DATE(ed)DO
select bill_master.bill_no,DATE_FORMAT(bill_master.bill_date, '%y/%m/%d') AS 'formatted_date',transaction.product_id,transaction.tax_amount,transaction.amount,transaction.amount-transaction.tax_amount as 'without_tax ',product_master.Product_name,product_master.vat from bill_master inner join transaction on bill_master.bill_no=transaction.bill_no inner join product_master on transaction.product_id=product_master.product_id where vat='14.50' and bill_master.bill_date=fd;
SET fd=DATE_ADD(fd,INTERVAL 1 DAY);
END WHILE;
END $$
DELIMITER;
calling statement:
CALL MonthlySalesReport('2016-03-06','2016-03-07');
error:
PROCEDURE aad_adr.MonthlySalesReport does not exist
Stored procedure create and drop statement have some problem, it have some space before name. Remove space and run command aad_adr.`
MonthlySalesReport(IN fromdate DATE, IN todate DATE)
Check space removed in below code.
DELIMITER $$
DROP PROCEDURE IF EXISTS `aad_adr`.`MonthlySalesReport` $$
CREATE PROCEDURE `aad_adr`.`MonthlySalesReport`(IN fromdate DATE,IN todate DATE)
BEGIN
Declare fd DATE;
Declare ed DATE;
SET fd=fromdate;
SET ed=todate;
WHILE DATE(fd)<=DATE(ed)DO
select bill_master.bill_no,DATE_FORMAT(bill_master.bill_date, '%y/%m/%d') AS 'formatted_date',transaction.product_id,transaction.tax_amount,transaction.amount,transaction.amount-transaction.tax_amount as 'without_tax ',product_master.Product_name,product_master.vat from bill_master inner join transaction on bill_master.bill_no=transaction.bill_no inner join product_master on transaction.product_id=product_master.product_id where vat='14.50' and bill_master.bill_date=fd;
SET fd=DATE_ADD(fd,INTERVAL 1 DAY);
END WHILE;
END $$
DELIMITER;

Clear handler before function return value to procedure mysql

I have the mysql version 5.5.38.
When I call a procedure that call a function inside there, handler condition its activated into function and raise up to procedure. I need that handler condition on function not affect the process on procedure. Included the function and procedure.
function:
DELIMITER $$
CREATE FUNCTION FUNCTION_HOURLY_GAS_CHANGE(INI_DATE DATETIME, TANK INT)
RETURNS INT
NOT DETERMINISTIC
BEGIN
DECLARE END_GAL INT;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET END_GAL = -1;
SET END_GAL = 0;
SELECT GALLONS INTO END_GAL
FROM TLS_TEMP_DATA WHERE FK_TANK = TANK
AND DATE LIKE CONCAT(DATE_FORMAT(DATE_ADD(DATE_FORMAT(INI_DATE, '%Y-%m-%d %H'), INTERVAL 1 HOUR), '%Y-%m-%d %H'),':%')
AND REQUEST_TYPE = 1;
RETURN END_GAL;
END $$
DELIMITER ;
procedure:
DELIMITER $$
CREATE PROCEDURE HOURLY_GAS_CHANGE(IN dateReport char(50), IN tank INT)
BEGIN
DECLARE COMPLETELOOP INT DEFAULT 0;
DECLARE INI_DATE DATETIME;
DECLARE INI_GAL INT;
DECLARE END_GAL INT;
DECLARE DIFF INT;
DECLARE V_HOUR CHAR(50);
DECLARE V_INI_GAL CHAR(50);
DECLARE V_END_GAL CHAR(50);
DECLARE V_DIFF CHAR(50);
DECLARE INITIALDATA CURSOR FOR
SELECT
DATE, GALLONS FROM TLS_TEMP_DATA WHERE FK_TANK = tank
AND (DATE BETWEEN CONCAT(dateReport, ' 00:00:00') AND CONCAT(dateReport, ' 23:59:59')) AND REQUEST_TYPE = 1
ORDER BY ID;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET COMPLETELOOP = 1;
DROP TEMPORARY TABLE IF EXISTS HOURLYGASCHANGE;
CREATE TEMPORARY TABLE HOURLYGASCHANGE(
`HOUR_DATA` CHAR(50) NOT NULL,
`INI_GAL` CHAR(50) NOT NULL,
`END_GAL` CHAR(50) NOT NULL,
`DIFF` CHAR(50) NOT NULL)
ENGINE=MEMORY;
OPEN INITIALDATA;
READ_LOOP: LOOP
FETCH INITIALDATA INTO INI_DATE, INI_GAL;
IF COMPLETELOOP THEN
LEAVE READ_LOOP;
END IF;
SET END_GAL = 1;
SET END_GAL = FUNCTION_HOURLY_GAS_CHANGE(INI_DATE, tank);
IF END_GAL > 0 THEN
SET DIFF = (END_GAL - INI_GAL);
SET V_DIFF = CAST(DIFF AS CHAR(50));
SET V_END_GAL = CAST(END_GAL AS CHAR(50));
ELSE
SET V_DIFF = 'N/A';
SET V_END_GAL = 'NOT UPDATED';
END IF;
SET V_INI_GAL = CAST(INI_GAL AS CHAR(50));
SET V_HOUR = CAST(DATE_FORMAT(INI_DATE, '%H') AS CHAR(50));
INSERT INTO HOURLYGASCHANGE VALUES(V_HOUR, V_INI_GAL, V_END_GAL, V_DIFF);
END LOOP;
close INITIALDATA;
SELECT * FROM HOURLYGASCHANGE;
END $$
DELIMITER ;
I can't fix the problem, but I found a solution to replace the function, I capture empty result into IFNULL function and now I can set a specific value when select show me a empty result.
SELECT (
IFNULL(
(
SELECT ENDTLS.GALLONS
FROM TLS_TEMP_DATA ENDTLS
WHERE ENDTLS.FK_TANK = tank
AND ENDTLS.DATE LIKE ONCAT(DATE_FORMAT(DATE_ADD(DATE_FORMAT(INI_DATE, '%Y-%m-%d %H'), INTERVAL 1 HOUR), '%Y-%m-%d %H'),':%')
AND ENDTLS.REQUEST_TYPE = 1
)
, -1)
) INTO END_GAL;

MySQL Stored Procedure Select Check Insert

So I'm trying to create a stored procedure in MySQL version 5.5.
I'm not sure what is wrong but what I want to accomplish is.
Get record From Table-A that over 7 days old. And then insert into Table-B, but I need to check if it is exist in Table B. If it is exists then skip, else Insert it.
So here is my code:
DROP PROCEDURE IF EXISTS `move_record`;
DELIMITER //
CREATE PROCEDURE `move_record`()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE dt DATETIME;
DECLARE uid,value BIGINT(20);
DECLARE category VARCHAR(30);
DECLARE data,comments VARCHAR(255);
DECLARE cancel TINYINT(1) DEFAULT NULL;
DECLARE curs CURSOR FOR SELECT `datetime`,user_id,category,data,comments,cancel FROM `record` WHERE `datetime` < DATE_SUB(CURDATE(), INTERVAL 7 DAY);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN curs;
myloop: LOOP
FETCH NEXT FROM curs INTO dt,uid,category,data,comments,cancel;
IF done THEN
LEAVE myloop;
END IF;
IF NOT EXISTS (SELECT * FROM `record_arc`
WHERE record_arc.`datetime` = dt
AND record.user_id = uid )
INSERT INTO `record_arc` (`datetime`,user_id,category,data,comments,cancel) VALUES (dt,uid,category,data,comments,cancel);
END IF;
END LOOP myloop;
CLOSE curs;
DEALLOCATE curs;
END//
DELIMITER ;
Maybe you can do this without a loop.
INSERT INTO `record_arc`(
`datetime`,
user_id,
category,
data,
comments,
cancel
)
SELECT
`datetime`,
user_id,
category,
data,
comments,
cancel
FROM `record` r
WHERE
`datetime` < DATE_SUB(CURDATE(), INTERVAL 7 DAY)
AND NOT EXISTS(
SELECT 1
FROM `record_arc` r2
WHERE
r2.`datetime` = r.`datetime`
AND r2.user_id = r.user_id
)
Alias name you used it wrongly. Check the below code
IF NOT EXISTS (SELECT 1 FROM `record_arc`
WHERE record_arc.`datetime` = dt
AND record_arc.user_id = uid )