I am stuck at this for the past hour and unable to convert this MSSQL Server stored procedure to "MySQL query":
DECLARE #LedgerTbl TABLE (PARTY_ID VARCHAR(100),VRDATE VARCHAR(200),
VRNOA VARCHAR(200),ETYPE VARCHAR(50),
DESCRIPTION VARCHAR(500),DEBIT DECIMAL,
CREDIT DECIMAL, RunningTotal decimal)
DECLARE #RunningTotal decimal
SET #RunningTotal = 0
INSERT INTO #LedgerTbl
SELECT PARTY_ID,VRDATE,DCNO VRNOA,ETYPE,DESCRIPTION,DEBIT,CREDIT, null
FROM PLEDGER WHERE PARTY_ID=#partyId AND VRDATE BETWEEN #from AND #to
ORDER BY VRDATE,ETYPE,VRNOA
UPDATE #LedgerTbl
SET #RunningTotal = RunningTotal = #RunningTotal + (DEBIT-CREDIT)
FROM #LedgerTbl
SELECT * FROM #LedgerTbl
How may I convert this to a single MySQL query or a MySQL Stored procedure?
UPDATE
I tried to transform it to but it is giving me these error that I have given below:
DELIMETER //
CREATE PROCEDURE `Acc_Ledger` ()
BEGIN
DECLARE RunningTotal DECIMAL;
SET RunningTotal = 0;
CREATE TEMPORARY TABLE LedgerTbl (PARTY_ID VARCHAR(100),VRDATE VARCHAR(200),VRNOA VARCHAR(200),ETYPE VARCHAR(50),DESCRIPTION VARCHAR(500),DEBIT DECIMAL,RTotal decimal);
INSERT INTO LedgerTbl
SELECT PARTY_ID,VRDATE,DCNO VRNOA,ETYPE,DESCRIPTION,DEBIT,CREDIT, null
FROM PLEDGER WHERE PARTY_ID=17 AND VRDATE BETWEEN '2013/12/02' AND '2010/12/02'
ORDER BY VRDATE,ETYPE,VRNOA;
UPDATE LedgerTbl
SET RunninTotal = RTotal = RunningTotal + (DEBIT-CREDIT)
FROM LedgerTbl;
SELECT * FROM LedgerTbl;
END//
DELIMETER;
Here are the errors:
There seems to be an error in your SQL query. The MySQL server error output below, if there is any, may also help you in diagnosing the problem
ERROR: Unknown Punctuation String # 10 STR: // SQL: DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal DECIMAL;DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal DECIMAL;DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal DECIMAL;DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal DECIMAL;DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal DECIMAL;DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal DECIMAL;DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal DECIMAL;DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal DECIMAL;
SQL query:
DELIMETER// CREATE PROCEDURE Acc_Ledger () BEGIN DECLARE
RunningTotal DECIMAL;
MySQL said: Documentation
#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 'DELIMETER//
CREATE PROCEDURE Acc_Ledger () BEGIN
DECLARE RunningTotal' at line 1
Can anyone please review it?
It seems that the MSSQL procedure calculates a running total,
I've tested this procedure (slighly modified) on sqlfiddle and it gives the following results:
http://www.sqlfiddle.com/#!6/0e909/1
The MSSQL procedure contains probably a typo here: SELECT PARTY_ID,VRDATE,DCNO VRNOA,ETYPE, it's not clear whether DCNO VRNOA are two separate columns, or maybe one column DCNO_VRNOA with "missing" underscore between them.
I assume that they are two separate columns.
To calculate a running total in MySql there is no need to use a temporary table.
This simple query does this task:
SELECT PARTY_ID,VRDATE,DCNO, VRNOA,ETYPE,DESCRIPTION,
DEBIT,
CREDIT,
#RunningTotal := #RunningTotal + (DEBIT-CREDIT) RunningTotal
FROM PLEDGER ,
( SELECT #RunningTotal:=0) init_variables
WHERE PARTY_ID=1
AND VRDATE BETWEEN '2013-11-11' AND '2013-11-11'
ORDER BY VRDATE,ETYPE,VRNOA;
See demo here: --> http://www.sqlfiddle.com/#!2/daa6e/1
The procedure might look like:
DELIMITER /
CREATE PROCEDURE `Acc_Ledger` ()
BEGIN
SELECT PARTY_ID,VRDATE,DCNO, VRNOA,ETYPE,DESCRIPTION,
DEBIT,
CREDIT,
#RunningTotal := #RunningTotal + (DEBIT-CREDIT) RunningTotal
FROM PLEDGER ,
( SELECT #RunningTotal:=0) init_variables
WHERE PARTY_ID=1
AND VRDATE BETWEEN '2013-11-11' AND '2013-11-11'
ORDER BY VRDATE,ETYPE,VRNOA;
END /
DELIMITER ;
I had to write this procedure on my own, here is the link that helped me understand the Stored Procedures in MySQL: http://net.tutsplus.com/tutorials/an-introduction-to-stored-procedures/. And the procedure that I came up wit
DROP PROCEDURE IF EXISTS `Acc_Ledger`;
DELIMITER //
CREATE PROCEDURE `Acc_Ledger` ()
BEGIN
DECLARE RunningTotal, deb, cred DECIMAL(19,2);
DECLARE counter, row_count int;
SET RunningTotal = 0;
SET counter = 1;
DROP TABLE IF EXISTS LedgerTbl;
CREATE TEMPORARY TABLE LedgerTbl (CTR int primary key auto_increment, PARTY_ID INT,VRDATE VARCHAR(200),VRNOA VARCHAR(200),ETYPE VARCHAR(50),DESCRIPTION VARCHAR(500),DEBIT DECIMAL(19,2),CREDIT DECIMAL(19,2),RTotal DECIMAL(19,2));
INSERT INTO LedgerTbl
SELECT 0, PARTY_ID,VRDATE,DCNO,ETYPE,DESCRIPTION,DEBIT,CREDIT, null FROM PLEDGER WHERE PARTY_ID=17 AND VRDATE BETWEEN '2010/10/02' AND '2013/12/02'
ORDER BY VRDATE,ETYPE,DCNO;
SELECT COUNT(*) INTO row_count FROM LedgerTbl;
WHILE counter <= row_count DO
SELECT debit INTO deb FROM LedgerTbl WHERE ctr = counter;
SELECT credit INTO cred FROM LedgerTbl WHERE ctr = counter;
SET RunningTotal = RunningTotal + (deb-cred);
UPDATE LedgerTbl
SET LedgerTbl.RTotal = RunningTotal
WHERE ctr = counter;
SET counter = counter + 1;
END WHILE;
SELECT * FROM LedgerTbl;
END//
DELIMITER ;
UPDATE
Now I found the comparatively efficient solution:
DROP PROCEDURE IF EXISTS `Acc_Ledger`;
DELIMITER //
CREATE PROCEDURE `Acc_Ledger` ()
BEGIN
DECLARE RunningTotal, deb, cred DECIMAL(19,2);
DECLARE counter, row_count int;
SET RunningTotal = 0;
SET counter = 1;
DROP TABLE IF EXISTS LedgerTbl;
CREATE TEMPORARY TABLE LedgerTbl (CTR int primary key auto_increment, PARTY_ID INT,VRDATE VARCHAR(200),VRNOA VARCHAR(200),ETYPE VARCHAR(50),DESCRIPTION VARCHAR(500),DEBIT DECIMAL(19,2),CREDIT DECIMAL(19,2),RTotal DECIMAL(19,2));
INSERT INTO LedgerTbl
SELECT 0, PARTY_ID,VRDATE,DCNO,ETYPE,DESCRIPTION,DEBIT,CREDIT, null FROM PLEDGER WHERE PARTY_ID=17 AND VRDATE BETWEEN '2010/10/02' AND '2013/12/02'
ORDER BY VRDATE,ETYPE,DCNO;
SELECT COUNT(*) INTO row_count FROM LedgerTbl;
SET #RunningTotal := 0;
UPDATE LedgerTbl
SET RTotal = (#RunningTotal := #RunningTotal + (DEBIT - CREDIT));
SELECT * FROM LedgerTbl;
END//
DELIMITER ;
Related
CREATE TABLE ZAMOWIENIA( id_zamowienia INT PRIMARY KEY NOT NULL,
id_uzytkownika INT, kwota_zamowienia DECIMAL(10,2));
INSERT INTO
ZAMOWIENIA VALUES (1,1,20), (2,4 ,5), (3,3,100), (4,1,300),
(5,2,80), (6, 1,150);
SELECT * FROM ZAMOWIENIA;
select
count(id_uzytkownika) from ZAMOWIENIA WHERE id_uzytkownika=1;
DROP
FUNCTION AccountType;
DELIMITER //
CREATE FUNCTION AccountType(
in_id_uzytkownika INT) RETURNS VARCHAR(20) DETERMINISTIC
BEGIN
DECLARE account_type VARCHAR(20);
DECLARE in_id_uzytkownika INT;
DECLARE zamowienia INT;
select count(id_uzytkownika) AS zamowienia
from ZAMOWIENIA
WHERE id_uzytkownika=in_id_uzytkownika;
select zamowienia from zamowienia;
IF zamowienia >10 THEN
SET account_type = 'BRONZE';
END IF;
IF zamowienia >30 THEN
SET account_type = 'SILVER';
END IF;
IF zamowienia >60 THEN
SET account_type = 'GOLD';
END IF;
return account_type;
END // DELIMITER ;
If you want to set a variable to the result of a SELECT query, you need to use SELECT ... INTO variable, not SELECT ... AS variable. Your function is trying to return the result of the SELECT query because it doesn't store the result into a variable.
Or you can use SET statement, which is simpler when you're just setting a single variable.
So replace the two SELECT statements with:
SET zamowienia = (SELECT COUNT(*) FROM from ZAMOWIENIA
WHERE id_uzytkownika=in_id_uzytkownika);
Also, you shouldn't have DECLARE statements for the function parameters. Remove the line
DECLARE in_id_uzytkownika INT;
i have created one stored procedure for sum of perticular condition but getting syntax error.
create table script :
CREATE TABLE count_smaller_coverage (count_records INT(11) ,block_id INT(11))
insert data :
INSERT INTO count_smaller_coverage
SELECT '114000','1' UNION
SELECT '112000','2' UNION
SELECT '98765','3' UNION
SELECT '78965','4' UNION
SELECT '4125','5' UNION
SELECT '123654','6' UNION
SELECT '78999','7' UNION
SELECT '89888','8' UNION
SELECT '99654','9' UNION
SELECT '75365','10' UNION
SELECT '25638','11' UNION
SELECT '85236','12' UNION
SELECT '65478','13' UNION
SELECT '65478','14' UNION
SELECT '85236','15'
Stored Procedure :
DELIMITER $$
DROP PROCEDURE IF EXISTS test_mysql_while_loop$$
CREATE PROCEDURE test_mysql_while_loop()
BEGIN
DECLARE strat INT;
DECLARE END INT;
DECLARE SumofCount BIGINT;
DECLARE block_id VARCHAR(2000);
SET strat=(SELECT MIN(block_id) FROM count_smaller_coverage);
SET END =(SELECT MAX(block_id) FROM count_smaller_coverage);
CREATE TABLE blocks_parts (block_id VARCHAR(2000), Counts BIGINT);
test: WHILE strat<=END DO
BEGIN
IF SumofCount > 800000 THEN
SET SumofCount=0;
SET block_id = NULL;
END IF;
SET SumofCount=COALESCE(SumofCount,0)+(SELECT count_records FROM count_smaller_coverage WHERE block_id=strat);
SELECT block_id = (COALESCE(block_id + ',', '') + CAST(block_id AS CHAR)) AS id FROM count_smaller_coverage WHERE block_id=strat;
IF SumofCount BETWEEN 800000 AND 1000000 THEN
INSERT INTO blocks_parts(block_id,Counts) VALUES (block_id,SumofCount);
END IF;
IF SumofCount BETWEEN 800000 AND 100000 THEN
LEAVE test;
END IF;
SET strat=strat+1;
END test;
END$$
DELIMITER ;
Error :
Query: CREATE PROCEDURE test_mysql_while_loop() BEGIN DECLARE strat INT; DECLARE end INT; DECLARE SumofCount BIGINT; DECLARE block_id V...
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 'test;
END' at line 33
Execution Time : 0 sec
Transfer Time : 0 sec
Total Time : 0.060 sec
You have a couple of issues in your procedure. Firstly, you have an unnecessary BEGIN after the DO in your WHILE statement. You can either remove that or match it with an END. Secondly, you need to end the WHILE loop with an END WHILE, in your case adding the test label to that statement. This should work:
test: WHILE strat<=END DO
-- BEGIN -- if you put BEGIN here ...
IF SumofCount > 800000 THEN
SET SumofCount=0;
SET block_id = NULL;
END IF;
SET SumofCount=COALESCE(SumofCount,0)+(SELECT count_records FROM count_smaller_coverage WHERE block_id=strat);
SELECT block_id = (COALESCE(block_id + ',', '') + CAST(block_id AS CHAR)) AS id FROM count_smaller_coverage WHERE block_id=strat;
IF SumofCount BETWEEN 800000 AND 1000000 THEN
INSERT INTO blocks_parts(block_id,Counts) VALUES (block_id,SumofCount);
END IF;
IF SumofCount BETWEEN 800000 AND 100000 THEN
LEAVE test;
END IF;
SET strat=strat+1;
-- END -- ... you must put END here
END WHILE test;
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `Test`$$
CREATE DEFINER=`root`#`%` PROCEDURE `Test`()
BEGIN
SET #SumofCount=0;
SET #block_id='';
SET #Start=(SELECT MIN(block_id) FROM count_smaller_coverage);
SET #End =(SELECT MAX(block_id) FROM count_smaller_coverage);
SET #v1=5;
myloop: WHILE #Start<=#End DO
IF #SumofCount > 800000 THEN
SET #SumofCount=0;
END IF;
SET #SumofCount=(IFNULL(#SumofCount,0)+(SELECT count_records FROM count_smaller_coverage WHERE block_id=#Start));
SET #block_id = (SELECT CONCAT(#block_id ,CAST(block_id AS CHAR),',') AS id FROM count_smaller_coverage WHERE block_id=#Start);
IF #SumofCount BETWEEN 800000 AND 1000000 THEN
SET #block_id = CONCAT(LEFT(#block_id, CHAR_LENGTH(#block_id) -1), '');
INSERT INTO blocks_parts(block_id,Counts) VALUES (#block_id,#SumofCount);
SET #block_id='';
END IF;
IF #Start = #End THEN
SET #block_id = CONCAT(LEFT(#block_id, CHAR_LENGTH(#block_id) -1), '');
INSERT INTO blocks_parts(block_id,Counts) VALUES (#block_id,#SumofCount);
END IF;
SET #Start=#Start+1;
END WHILE myloop;
END$$
DELIMITER ;
I have been trying to execute the following query without any luck. It says:
#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 '' at line 32
I am unable to point out any errors. Can anyone please tell me what am I doing wrong here?
DELIMITER $$
--
-- Procedures
--
CREATE PROCEDURE `Acc_Ledger`(IN `startDate` VARCHAR(200), IN `endDate` VARCHAR(200), IN `p_id` INT)
BEGIN
DECLARE RunningTotal, deb, cred DECIMAL(19,2);
DECLARE counter, row_count int;
SET RunningTotal = 0;
SET counter = 1;
DROP TABLE IF EXISTS LedgerTbl;
CREATE TEMPORARY TABLE LedgerTbl (CTR int primary key auto_increment, PARTY_ID INT,VRDATE VARCHAR(200),VRNOA VARCHAR(200),ETYPE VARCHAR(50),DESCRIPTION VARCHAR(500),DEBIT DECIMAL(19,2),CREDIT DECIMAL(19,2),RTotal DECIMAL(19,2));
INSERT INTO LedgerTbl
SELECT null, PARTY_ID,VRDATE,DCNO,ETYPE,DESCRIPTION,DEBIT,CREDIT, null FROM pledger WHERE PARTY_ID=p_id AND DATE(VRDATE) BETWEEN startDate AND endDate
ORDER BY VRDATE,ETYPE,DCNO;
SET #RunningTotal := 0;
SELECT SUM(DEBIT)-SUM(CREDIT) FROM pledger WHERE DATE(VRDATE) < startDate AND party_id = p_id INTO #RunningTotal;
IF ISNULL(#RunningTotal) THEN
SET #RunningTotal := 0;
END IF;
UPDATE LedgerTbl
SET RTotal = (#RunningTotal := #RunningTotal + (DEBIT - CREDIT));
SELECT * FROM LedgerTbl;
END$$
I missed
DELIMITER ;
at the end of query. Added this and everything is working fine.
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;
I have a little problem. Looks like the procedure does not exist. Somehow it's dropped after the creation. I get different error each time i change something. I'm not really sure what's causing the error, maybe I'm not allowed to drop procedures and creating them in the same query.
I hope you guys can help me out.
drop procedure if exists refIntChk;
DELIMITER //
CREATE PROCEDURE refIntChk(IN district INT(11), OUT b INT(1))
BEGIN
DECLARE b INT(1);
IF district IN (select dist FROM t13)
THEN
SET b = 1;
ELSE
SET b = 0;
END IF;
END; //
DELIMITER ;
drop procedure gen if exists ;
DELIMITER //
CREATE PROCEDURE gen()
BEGIN
DECLARE rows INT(11) DEFAULT (SELECT COUNT(dist) FROM t13);
DECLARE district INT(11);
DECLARE custname VARCHAR(16);
DECLARE revenue FLOAT;
DECLARE x INT DEFAULT 10000;
DECLARE outvar INT(11);
WHILE x > 0
DO
SET district = FLOOR(RAND()*rows)+1;
CALL refIntChk(district, outvar);
IF outvar = 1
THEN
SET custname = substring(MD5(RAND()), -16);
SET revenue = (RAND() * 10);
INSERT INTO t14 VALUES(NULL, custname, district, revenue);
SET x = x - 1;
END IF;
END WHILE;
END;//
DELIMITER ;
CALL gen();
When you get errors, it's usually good to run each statement, one by one, and see which one is producing the error.
The second DROP procedure statement should be:
drop procedure if exists gen;