I dont't understand why im getting syntax error on my sp code below. Can anyone help me figure this out?
SQL Error (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 'DECLARE CUR1 CURSOR FOR SELECT pc.prospectus_courses_id FROM
prereq_cou' at line 8
DELIMITER $$
DROP PROCEDURE IF EXISTS get_prereqs3$$
CREATE PROCEDURE get_prereqs3(IN prosp_courses_id SMALLINT(5))
BEGIN
DECLARE done int DEFAULT FALSE;
DECLARE required SMALLINT(5) default 0;
DECLARE to_search SMALLINT(5) default 0;
DROP TABLE IF EXISTS tmp_list;
CREATE TABLE tmp_list(courses_id SMALLINT(5), courses_id_req SMALLINT(5)) ENGINE = MEMORY;
DECLARE CUR1 CURSOR FOR SELECT pc.prospectus_courses_id
FROM prereq_courses pc
JOIN prerequisites pr on (pr.id = pc.prerequisites_id)
JOIN prospectus_courses ps on (ps.id = pr.prospectus_courses_id)
WHERE ps.id = to_search
MAIN_LOOP: LOOP
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
FETCH cur1 INTO required;
IF done THEN
CLOSE cur1;
LEAVE main_loop;
ELSE
insert into tmp_list values (to_search, required);
set to_search = required;
iterate main_loop;
END IF;
END LOOP;
select c.course_code
from tmp_list t
join prospectus_courses pc on pc.id = t.courses_id_req
join courses c on c.id = pc.courses_id ;
drop table tmp_list;
END$$
DELIMITER ;
Declarations have to be right after a BEGIN block.
In your case just move the DECLARE cur1 CURSOR and DECLARE CONTINUE HANDLER.. two lines up.
Sometimes you want to declare a variable or cursor later in the code, for example only, if a condition is met.
In this case you can wrap the block with a nested BEGIN .. END again.
http://dev.mysql.com/doc/refman/5.5/en/begin-end.html and
http://dev.mysql.com/doc/refman/5.5/en/declare.html
DECLARE is permitted only inside a BEGIN ... END compound statement and must be at its start, before any other statements.
Also you are declaring CUR1 but using cur1.
Is there no need semicolon?
WHERE ps.id = to_search;
^___________
Related
I'm trying to make a Nested Cursor in Mysql by following this instruction.
Then i got this issue:
#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 activityids CURSOR FOR SELECT activity_id FROM #_activity;
END BLOCK2;' at line 22
I've 2 table 'account' and 'n_activity' (n = account_id in table 'account')
Ex: i've table 'account' and '20_activity'.
So i want to loop the 'account_id' and get the 'activity_id' from that loop.
Here is my code:
DROP PROCEDURE if exists update_schema_activity_startdate_and_duedate;
DELIMITER $$
CREATE PROCEDURE update_schema_activity_startdate_and_duedate()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE accountid INT;
--
-- GET ALL ACCOUNT ID
--
DECLARE accountids CURSOR FOR SELECT account_id FROM account;
--
-- LOOP
--
OPEN accountids;
read_loop: LOOP
FETCH accountids INTO accountid;
BLOCK2: BEGIN
SET #_activity = CONCAT(accountid,'_activity');
DECLARE activityids CURSOR FOR SELECT activity_id FROM #_activity;
END BLOCK2;
END LOOP;
CLOSE accountids;
END$$
DELIMITER ;
CALL update_schema_activity_startdate_and_duedate();
Please help, thanks.
DELIMITER ##
create trigger tra_Price after update on assets_cdn_charge for each row
begin
declare res int;
declare ids int;
declare idq int;
declare idt int;
set res = (select price from assets_cdn_charge where price = new.price);
set ids = (select id from assets_cdn_charge where price = new.price);
DECLARE cur CURSOR FOR SELECT id FROM assets_cdn_composite WHERE cdn_charge_id = ids;
open cur;
ins_loop:LOOP
fetch cur into idq;
declare curs cursor for select id from assets_cdn_traffic where domain_name_id = idq;
open curs;
ins1_loop:LOOP
fetch curs into idt;
update assets_cdn_traffic set cost = traffic * res where domain_namd_id = idt;
end LOOP;
close curs;
end LOOP;
close cur;
END; ##
when I run this code,I had get this error:
ERROR 1064 (42000): 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 'DECLARE cur CURSOR FOR SELECT id FROM
assets_cdn_composite WHERE cdn_charge_id =' at line 9
Probably because:
DECLARE is permitted only inside a BEGIN ... END compound statement
and must be at its start, before any other statements.
...so that line should likely be moved before the two set statements above that point.
I believe that you're going to have other trouble if that fixes that error, because I don't know what you expect that query to retrieve as idq is declared before that point, but is not set to any value?
=====
UPDATE:
Below is an example from a previous comment about the possibility to eliminate cursors altogether. Try this:
BEGIN
UPDATE assets_cdn_traffic
JOIN assets_cdn_composite ON assets_cdn_traffic.domain_name_id = assets_cdn_composite.cdn_charge_id
JOIN assets_cdn_charge ON assets_cdn_charge.id = assets_cdn_composite.cdn_charge_id
SET cost = traffic * NEW.price
WHERE assets_cdn_charge.id = NEW.id
END
However, I would try the update query separately before using in the trigger to make sure that it works as expected. Replace the NEW.price and the NEW.id with test values to verify the handling.
I have a stored procedure in Mysql database like this:
DELIMITER $$
USE `vboard_75`$$
DROP PROCEDURE IF EXISTS `sp_LongWaitCall`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_LongWaitCall`()
BEGIN
UPDATE cdr SET cdr.CallStatus='DISCONNECTED',cdr.EndTime=NOW() WHERE cdr.CallStatus='RINGINGIN'
AND MINUTE(DATEDIFF(cdr.StartTime,NOW())) >=7;
DECLARE _StatVal FLOAT;
DECLARE _DevID INT;
DECLARE Record_Fetch INT DEFAULT 0;
DECLARE crsr_Board CURSOR FOR
SELECT IFNULL(MAX(SECOND(DATEDIFF(CDR.StartTime, IFNULL(CDR.EndTime, NOW())))), 0) AS LRT,vw_Boards_Ext.boardid
FROM vw_Boards_Ext RIGHT OUTER JOIN
boards ON vw_Boards_Ext.boardid = boards.boardid LEFT OUTER JOIN
CDR ON vw_Boards_Ext.Ext = CDR.DDI AND
STR_TO_DATE(CONCAT(boards.ResetDate,' ',boards.ResetTime),'%m/%d/%Y %H:%i') < CDR.timestamp
AND CDR.CallStatus='RINGINGIN'
GROUP BY vw_Boards_Ext.boardid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET Record_Fetch = 1;
OPEN crsr_Board;
FETCH crsr_Board INTO _StatVal, _DevID;
WHILE Record_Fetch = 0 DO
UPDATE stat_values AS sv SET sv.StatValue = _StatVal,sv.timestamp= NOW()
WHERE sv.itemId = _DevID AND sv.itemType = 'boards' AND sv.StatId = 3;
FETCH crsr_Board INTO _StatVal, _DevID;
END WHILE;
CLOSE crsr_Board;
DEALLOCATE PREPARE crsr_Board;
END$$
DELIMITER ;
Error:
Query: CREATE DEFINER=root#localhost PROCEDURE sp_LongWaitCall() BEGIN update cdr set cdr.CallStatus='DISCONNECTED',cdr.EndTime=n...
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 _StatVal FLOAT;
DECLARE _DevID INT;
DECLARE Record_Fetch INT DEFAULT 0' at line 8
Execution Time : 0 sec
Transfer Time : 0 sec
Total Time : 0.001 sec
This documentation refers to having the DECLARE statements at the top and also before the creation of any CURSORS and HANDLERS, which you are following but not at the beginning of the BEGIN... END block.
This documentation clarifies the question that OP had posted!
It is mandatory to have your declarations at the begin of your BEGIN... END block, but not under an UPDATE statement.
Additional reference to a similar issue can be found on this question, even which refers to the same solution.
Hope this helps!
It's my first time working with cursors on MySQL, and I am having some problems, it doesn't accept the declaration of my cursor, what's wrong with my code? it shows me this error messagae:
#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 'DECLARE #MyCursor CURSOR' at line 1
and my code is:
DECLARE #MyCursor CURSOR;
DECLARE #MyField varchar2(255);
BEGIN
SET #MyCursor = CURSOR FOR
SELECT codeMaint from affectationmc where iduser=29;
OPEN #MyCursor
FETCH NEXT FROM #MyCursor
INTO #MyField
WHILE ##FETCH_STATUS = 0
BEGIN
delete from mcorr where codemaint=#MyField ;
FETCH NEXT FROM #MyCursor
INTO #MyField
END;
CLOSE #MyCursor ;
DEALLOCATE #MyCursor;
END;
here is the template I use for cursors. It just taking the items from the select and maps them into the variables declared up top and executes your statement. Once it processes the statement in the section --Actions to Loop Here, it changes the variables by selecting the next row from your select statement. This repeats until it process all of the rows in the select.
DECLARE
#variable_A AS varchar(15)
,#variable_B AS INT
,#variable_C AS INT
,#variable_D AS VARCHAR(255)
DECLARE Process_Name CURSOR LOCAL FAST_FORWARD FOR
SELECT
T.Col_A,T.Col_B,T.Col_C,T.Col_D
FROM
tab.my_table AS T;
OPEN Process_Name
FETCH NEXT FROM Process_Name INTO #variable_A,#variable_B,#variable_C,#variable_D
WHILE ##FETCH_STATUS = 0
BEGIN
--Actions to Loop Here
FETCH NEXT FROM Process_Name INTO #variable_A,#variable_B,#variable_C,#variable_D
END
CLOSE Process_Name
DEALLOCATE Process_Name
You're attempting to declare your cursor in one statement, then associate the query with it in a second statement. While some databases will allow this, I'm fairly sure MySQL isn't one of them. Also, MySQL is quite strict about not declaring cursors until after all variables have been declared.
Here's how I would do it:
BEGIN -- note all declarations are inside the BEGIN/END
DECLARE done INT DEFAULT FALSE; -- Good practice is to avoid global variables whenever possible
DECLARE MyField varchar(255); -- varchar2 is Oracle, not MySQL
DECLARE MyCursor CURSOR FOR
SELECT codeMaint
FROM affectationmc
WHERE iduser = 29;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET done = TRUE; -- this will detect end-of-result-set
OPEN MyCursor;
read_loop: LOOP
FETCH NEXT
FROM MyCursor
INTO MyField;
IF done THEN
LEAVE read_loop;
END IF;
DELETE FROM mcorr
WHERE codemaint = MyField ;
END LOOP;
CLOSE MyCursor;
END;
DROP TRIGGER IF EXISTS `ACTUALIZAR_LOTE_DETALLE`;
DELIMITER //
CREATE TRIGGER `ACTUALIZAR_LOTE_DETALLE` AFTER INSERT ON `detalle_envio`
FOR EACH ROW BEGIN
DECLARE ID_INVENTARIO_IN INT;
DECLARE ID_LOTE_DETALLE_MIN INT;
DECLARE CANTIDAD_A_COMPARAR INT;
DECLARE CANTIDAD_A_RESTAR INT;
SET CANTIDAD_A_RESTAR = new.cantidad_enviado;
SET ID_INVENTARIO_IN = (Select id_inventario from detalle_requisicion WHERE id_detalle_requisicion = new.id_detalle_requisicion);
DECLARE cur_id CURSOR FOR SELECT id_lote_detalle from lote_detalle WHERE id_inventario = ID_INVENTARIO_IN AND cantidad > 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET DONE = 1;
OPEN cur_id;
read_loop: LOOP
FETCH cur_id INTO LOTE_DETALLE_IDS;
SET CANTIDAD_A_COMPARAR = select cantidad from lote_detalle where id_lote_detalle = LOTE_DETALLE_IDS;
IF CANTIDAD_A_RESTAR > CANTIDAD_A_COMPARAR THEN
UPDATE `lote_detalle` SET cantidad=cantidad-CANTIDAD_A_COMPARAR WHERE id_lote_detalle = LOTE_DETALLE_IDS;
SET CANTIDAD_A_RESTAR = CANTIDAD_A_RESTAR - CANTIDAD_A_COMPARAR;
ELSE
UPDATE `lote_detalle` SET cantidad=cantidad-CANTIDAD_A_RESTAR WHERE id_lote_detalle = LOTE_DETALLE_IDS;
LEAVE read_loop;
END IF;
IF DONE = 1 THEN
LEAVE read_loop;
END IF;
END LOOP read_loop;
CLOSE cur_id;
END
//
DELIMITER ;
Is anything in the cursor?
the query or something?
Is anything in the Syntax?
Cause i have based this Trigger from the syntax of the MySQL Forums
This is the Error:
#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 'DECLARE cur_id CURSOR FOR SELECT id_lote_detalle from lote_detalle WHERE id_inve' at line 9
There are at least following issues with your code:
All declarations should come before any statements (SET in your case). That's what is causing your immediate error.
You didn't declare DONE variable
You didn't declare LOTE_DETALLE_IDS variable, but you declared ID_LOTE_DETALLE_MIN which you didn't use. Perhaps you should rename ID_LOTE_DETALLE_MIN to LOTE_DETALLE_IDS then.
Since declarations go first you have to re-write your cursor definition (e.g. with subquery) because ID_INVENTARIO_IN variable isn't initialized yet
Your whole declaration section can be re-written in a following manner
-- declaration of variables of the same type can be combined
DECLARE ID_INVENTARIO_IN,
LOTE_DETALLE_IDS,
CANTIDAD_A_COMPARARINT,
CANTIDAD_A_RESTAR,
DONE INT;
DECLARE cur_id CURSOR FOR ...
DECLARE CONTINUE HANDLER ...
-- initialize variables
SET ...
Now, I believe your trigger most likely can be re-written with just update statement(s). You can get help with it if you explain in plain words what you're trying to achieve and provide exact table schemas and sample data.