Let's see if I can edit this and put the whole procedure in.
I am trying to convert an Oracle database to MySQL. I have all the tables, keys, indexes, and views converted. I now need to convert a stored procedure to MySQL.
I have most of it done, and there is only one hang up on my code:
set dns1_tmp = X.X.X.X;
SET dns2_tmp = X.X.X.X;
This gives me an error of 1064 Syntax Error: Missing semicolon
I have tested the rest of my procedure, and it works fine. It creates it, runs it, and retrieves data from it, but only if I remove those two lines.
Any ideas on what I can do?
Whole stored procedure:
DELIMITER //
USE `TEST`//
DROP PROCEDURE IF EXISTS `proc_IN`//
CREATE DEFINER=`root`#`localhost` PROCEDURE `proc_IN`
(IN DNIS VARCHAR(20),
IN MSISDN VARCHAR(20),
IN AVPAIR1 VARCHAR(20),
IN AVPAIR2 VARCHAR(20),
IN GROUPID VARCHAR(20),
OUT DNS1 VARCHAR(15),
OUT DNS2 VARCHAR(15),
OUT AUTHSTAT VARCHAR(100))
BEGIN
declare dns1_tmp varchar(15);
declare dns2_tmp varchar(15);
set dns1_tmp = X.X.X.X;
SET dns2_tmp = X.X.X.X;
DECLARE avpair1_tmp varchar(15);
DECLARE avpair2_tmp varchar(15);
DECLARE grpid_tmp varchar(15);
DECLARE C_USER CURSOR FOR SELECT AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID FROM GRP, ALLMEMBER WHERE ALLMEMBER.GROUPID=GRP.GROUPID
UNION
SELECT AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID FROM GRP;
OPEN C_USER;
FETCH C_USER INTO AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID;
LOOP
FETCH C_USER INTO avpair1_tmp, avpair2_tmp, dns1_tmp, dns2_tmp, grpid_tmp;
INSERT INTO duplog VALUES(DNIS, MSISDN, avpair1_tmp, avpair2_tmp, dns1_tmp,dns2_tmp, grpid_tmp, SYSDATE);
END LOOP;
IF C_USER%ROWCOUNT > 1 THEN
INSERT INTO duplog VALUES(DNIS, MSISDN, AVPAIR1, AVPAIR2, DNS1,DNS2, GROUPID, SYSDATE);
SET AUTHSTAT := 'ok';
elseif C_USER%ROWCOUNT = 1 THEN
SET AUTHSTAT := 'ok';
ELSE
SET AUTHSTAT := NULL;
END IF;
CLOSE C_USER;
COMMIT;
END //
DELIMITER ;
Related
CREATE PROCEDURE insert_user(in uname varchar(20),in gender varchar(20),in email varchar(20),in phone varchar(20),in pword varchar(20),in city varchar(20))
BEGIN
DECLARE finished integer default 0;
Declare cnt integer default 0;
declare id integer;
DECLARE c_cur cursor for select user_id from user;
DECLARE CONTINUE HANDLE FOR NOT FOUND SET finished = 1;
open c_cur;
ins_user: loop
fetch c_cur into id;
IF finished = 1 THEN
LEAVE ins_user;
end if;
cnt:=id;
end loop ins_user;
cnt:=cnt+1;
insert into user
values(cnt,uname,email,phone,city,pword,gender);
END;
Am getting 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 'HANDLE FOR NOT FOUND SET finished = 1; open c_cur; ins_user: loop fetch ' at line 7
i am not sure where its getting wrong
Set the Delimiter to something else, other than ;, for eg: $$. This will allow the parser to treat the whole create statement as one.
At the end, redefine the Delimiter back to ;
user is a keyword in MySQL. It is better to rename your table to something else, or use backticks around it.
There is a typo; it should be HANDLER not HANDLE
Try:
DELIMITER $$
DROP PROCEDURE IF EXISTS insert_user $$
CREATE PROCEDURE insert_user(in uname varchar(20),
in gender varchar(20),
in email varchar(20),
in phone varchar(20),
in pword varchar(20),
in city varchar(20))
BEGIN
DECLARE finished INT DEFAULT 0;
Declare cnt INT DEFAULT 0;
declare id INT;
DECLARE c_cur CURSOR FOR select user_id from `user`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
open c_cur;
ins_user: loop
fetch c_cur into id;
IF finished = 1 THEN
LEAVE ins_user;
end if;
SET cnt:=id; -- set was missing here
end loop ins_user;
SET cnt:=cnt+1; -- set was missing here
insert into `user`
values(cnt,uname,email,phone,city,pword,gender);
END $$
DELIMITER ;
I have table group with begindate lesson count and weekdays columns. I would like write MySQL procedure for adding data to another table named lessons according to group. But I couldn't handle with syntax of MySQL. Could you please help me resolve problems with that procedure:
CREATE PROCEDURE simpleproc (IN idGroup INT, IN groupName varchar(20),IN beginDate date, IN weekday1 INT, IN weekday2 INT, IN lessonCount INT)
BEGIN
DECLARE i;
SET i:=1;
WHILE i<=lessonCount DO
DATE_ADD(beginDate,INTERVAL 1 DAY)
IF (WEEKDAY(beginDate)=weekday1) OR (WEEKDAY(beginDate)=weekday2) THEN
SET name:=groupName+i;
SET price:=DIV(price,8)
insert into lessons (lessonName, idGroup, lessonPrice, datePassed)
values (name,idGroup,price,begindate);
SET i:=i+1
END IF;
END WHILE;
END
After solving problems I will add this code to prepared statement in Java
This will run. Make sure: 1. That you increment i in a proper place of your code inside the while loop. 2. Avoid usind reserved words (like name) for fields and variables. 3. Define price variable somewhere before making integer division of it. You know the code and your tables' structure. Nobody is capable to do it for you.
DROP PROCEDURE IF EXISTS `simpleproc`;
DELIMITER ;;
CREATE DEFINER=`root`#`localhost` PROCEDURE `simpleproc`(IN idGroup INT, IN groupName varchar(20),IN beginDate date, IN weekday1 INT, IN weekday2 INT, IN lessonCount INT)
BEGIN
DECLARE i int;
DECLARE name1 int;
DECLARE price int;
SET i:=1;
WHILE i<=lessonCount DO
SET beginDate:=DATE_ADD(beginDate,INTERVAL 1 DAY);
IF WEEKDAY(beginDate) in(weekday1,weekday2) THEN
SET name1:=groupName+i;
SET price:=price DIV 8;
insert into lessons (lessonName, idGroup, lessonPrice, datePassed)
values (name1,idGroup,price,begindate);
END IF;
SET i:=i+1;
END WHILE;
END
;;
DELIMITER ;
This question already has answers here:
How To have Dynamic SQL in MySQL Stored Procedure
(3 answers)
Closed 8 years ago.
is it possible to set a variable to an insert statement in a stored procedure?
Something like:
set variable1 = insert into table(field1, field2, field3) values(val1, val2, variable2);
If so, how should it be written?
I keep throwing errors and documentation in the wild is inconclusive.
I was going for brevity but the entire procedure is thus:
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `new_accession`(in barcode int, in accepted varchar(11), in wt float(11,2), in wtunit varchar(3),in draw date, in chist varchar(256), in ghist varchar(256), in meds varchar(256), in diffdiag varchar(256),in diseasesus varchar(256),in volume int, in facility int, in patient int, in employ int, in compromised int, in receiving int, in test int)
BEGIN
declare accessionId int;
declare accessionTest int;
declare tkInsert varchar(256);
declare hptInsert varchar(256);
declare calInsert varchar(256);
declare pthInsert varchar(256);
declare vitdtkInsert varchar(256);
declare cnpInsert varchar(256);
if wtunit = 'lb' then set wt = convertLbKg(wt);
end if;
INSERT INTO accession(barcode_accession,accepted_accession,weight_accession,req_weight_units,draw_date_accession,cancer_history_accession,general_history_accession,medication_accession,differential_diagnosis_accession,disease_suspect_accession,volume_accession,facility_doctor_index_id_facility_doctor_index,patient_id_patient,employee_id_employee,accession_compromised_id_accession_compromised,receiving_id,accession_typeof_id_accession_typeof)
VALUES (barcode,accepted,wt,wtunit,draw,chist,ghist,meds,diffdiag,diseasesus,volume,facility,patient,employ,compromised,receiving,1);
set accessionId = last_insert_id();
set tkInsert = insert into pending(accession_facility_index,reagent_type,`status`)values(accessionId,1,'Pending');
set hptInsert = insert into pending(accession_facility_index,reagent_type,`status`)values(accessionId,2,'Pending');
set calInsert = insert into pending(accession_facility_index,reagent_type,`status`)values(accessionId,3,'Pending');
set pthInsert = insert into pending(accession_facility_index,reagent_type,`status`)values(accessionId,4,'Pending');
if test = 1 then tkInsert,calInsert;
elseif test =2 the hptInsert,pthInsert;
else pthInsert;
end if;
END
It is not very clear what you want but if your goal is to store insert's outcome (affected rows) you could use ROW_COUNT().
ROW_COUNT() returns the number of rows changed, deleted, or inserted
by the last statement if it was an UPDATE, DELETE, or INSERT.
For other statements, the value may not be meaningful.
For example:
variable1 = (select ROW_COUNT());
I think you're looking for prepared statements.
PREPARE tkInsert FROM CONCAT("insert into pending(accession_facility_index,reagent_type,`status`)values(?, 1,'Pending')";
Then you execute it with:
EXECUTE tkInsert USING accessionId;
I have a stored function in MySQL and it works partially.
DELIMITER $$
DROP FUNCTION IF EXISTS `getsubdomain`$$
CREATE FUNCTION getsubdomain(page_id int(11))
RETURNS CHAR(255)
DETERMINISTIC
READS SQL DATA
SQL SECURITY INVOKER
BEGIN
declare current_p_id int(11);
declare current_p_parent_id int(11);
declare current_p_address_type char(255);
declare current_p_adress char(255);
SET current_p_id = page_id;
WHILE (current_p_id) <> 0
DO
select p_parent_id, p_address_type, p_adress from opu_pages where p_id = current_p_id into current_p_parent_id, current_p_address_type, current_p_adress;
IF current_p_address_type <> ''
THEN
IF current_p_address_type = 'subdomain'
THEN
RETURN current_p_adress;
ELSE
SET current_p_id = current_p_parent_id;
END IF;
ELSE
RETURN NULL;
END IF;
END WHILE;
RETURN NULL;
END$$
DELIMITER ;
If I call in query SELECT getsubdomain(p_id) FROM opu_pages; it works Ok. But if I call it in SELECT * FROM opu_pages WHERE getsubdomain(p_id)='library'; the database is collapsed and freezing.
Query and function work with one table.
What did I do wrong?
I thought that it can be caused by the table format MyISAM. But I can't change it to InnoDB because I use FULLTEXTFORMAT fields in this table.
Table opu_pages (MyISAM) scheme
p_id INT
p_parent_id INT
p_address_type ENUM (path, subdomain)
p_adress VARCHAR
Based on your post I would say that your code is entering an infinite loop for some of your input parameters.
In particular the case where p_id = p_parent_id in the opu_pages table and the current_p_address_type = 'subdomain'
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;