MySQL - Error 1064 in Stored Proc SQL - mysql

I have written the following stored procedure which in HeidiSQL is giving me an Error 1064 at the line starting with SET pay_ref = SELECT CONCAT('KOS' ...
Let me firstly explain what's going on with this procedure. I have a table gamers with a BIGINT primary key with auto_increment. This proc is supposed to:
Take in some params from the user
Check if the user already exists in the db according to his/her email address, and spits back the word "DUPLICATE" if a reord does exist
Else it does the insert as normal
Then it reads in the ID of the new record created and converts it to a varchar, pads it with leading zeros and then gets concatenated with some other strings
This new string (which should read for example KOS00001ABCDEF) then gets updated to the pay_refcode field >>> this is how we have settled on generating a unique payment reference for the user
If all works out well it updates retval with the newly generated reference code to be read by PHP script.
DELIMITER //
CREATE PROCEDURE `InsertGamer` (
IN p_fname VARCHAR(30),
IN p_lname VARCHAR(30),
IN p_email VARCHAR(255),
IN p_favgame VARCHAR(60),
IN p_pay_suffix VARCHAR(6),
OUT retval VARCHAR(14)
)
BEGIN
DECLARE last_id BIGINT;
DECLARE pay_ref VARCHAR(14);
IF (EXISTS(SELECT * FROM gamers WHERE (email = p_email))) THEN
SET retval = 'DUPLICATE';
ELSE
INSERT INTO gamers (fname, lname, email, favgame, pay_refcode)
VALUES (p_fname, p_lname, p_email, p_favgame, NULL);
SET last_id = LAST_INSERT_ID();
SET pay_ref = SELECT CONCAT('KOS', (SELECT LPAD(CONVERT(last_id, VARCHAR(5)),5,'0')), p_pay_suffix);
UPDATE gamers
SET pay_refcode = pay_ref
WHERE application_id = last_id;
SET retval = pay_ref;
END IF;
END //
I cannot for the life of me figure out what the problem is and would sincerely appreciate any help from you. Thank you very much in advance!

You just need to remove the SELECT keyword from line which you set the value for pay_ref.
SET pay_ref = CONCAT('KOS', LPAD(CONVERT(last_id, CHAR(5)),5,'0'), p_pay_suffix);
full code:
DELIMITER //
CREATE PROCEDURE `InsertGamer` (
IN p_fname VARCHAR(30),
IN p_lname VARCHAR(30),
IN p_email VARCHAR(255),
IN p_favgame VARCHAR(60),
IN p_pay_suffix VARCHAR(6),
OUT retval VARCHAR(14)
)
BEGIN
DECLARE last_id BIGINT;
DECLARE pay_ref VARCHAR(14);
SET #count := (SELECT COUNT(*) FROM gamers WHERE email = p_email)
IF (#count > 0) THEN
SET retval = 'DUPLICATE';
ELSE
INSERT INTO gamers (fname, lname, email, favgame, pay_refcode)
VALUES (p_fname, p_lname, p_email, p_favgame, NULL);
SET last_id = LAST_INSERT_ID();
SET pay_ref = CONCAT('KOS', LPAD(CONVERT(last_id, CHAR(5)),5,'0'), p_pay_suffix);
UPDATE gamers
SET pay_refcode = pay_ref
WHERE application_id = last_id;
SET retval = pay_ref;
END IF;
END //
DELIMITER ;

Related

Cant get mysql procedure to work - syntax error

I'm wrote this mysql procedure for inserting customer billing details into an ecommerce database.
If i run this in phpmyadmin, it throws errors for any semicolons. I removed the semicolons but it gives the following 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 addr_id INT UNSIGNED ... at line 4
I've never worked with procedures before but i double checked the syntax and can't figure out the error.
DELIMITER //
CREATE PROCEDURE addCustomer(email VARCHAR(60), status VARCHAR(15), bill_pin_id SMALLINT UNSIGNED, bill_addr VARCHAR(175), name VARCHAR(60), tel VARCHAR(15))
BEGIN
DECLARE em_id INT UNSIGNED;
DECLARE addr_id INT UNSIGNED;
DECLARE cust_id INT UNSIGNED;
DECLARE sql_error TINYINT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET sql_error = true;
--check if customer email already exists
SELECT id INTO em_id FROM email_list WHERE email = email;
-- not sure of the return value, haven't tested it
IF em_id = 1 THEN
-- if emails exists check if customer exists
SELECT id INTO cust_id FROM customer WHERE email_list_id = em_id;
IF cust_id = 1 THEN
-- customer must have address information
SELECT address_id INTO addr_id from customer_addr
INNER JOIN address on address_id = address.id
WHERE customer_id = cust_id and address = bill_addr;
END IF
END IF
START TRANSACTION;
IF (em_id = 0) THEN
-- if email doesn't exist, no customer no address - simple insert
INSERT INTO email_list (email, status) VALUES (email, status);
SELECT LAST_INSERT_ID() INTO em_id;
INSERT INTO customer (email_list_id, full_name, phone)
VALUES (em_id, name, tel);
SELECT LAST_INSERT_ID() INTO cust_id;
INSERT INTO address (pincode_id, address) VALUES (bill_pin_id, bill_addr);
SELECT LAST_INSERT_ID() INTO addr_id;
INSERT INTO customer_addr (address_id, customer_id)
VALUES (addr_id, cust_id);
ELSE
UPDATE email_list SET status = status where id = em_id;
UPDATE customer SET full_name = name, phone = tel WHERE id = cust_id;
UPDATE address SET pincode_id = bill_pin_id, address = bill_addr;
END IF
IF sql_error = FALSE THEN
COMMIT;
SELECT 'SUCCESS';
ELSE
ROLLBACK;
SELECT 'FAILED';
END IF
END //
DELIMITER ;
Try this solution, I added some missing semicolons and spaces in some comments.
CREATE addCustomer(email VARCHAR(60), status VARCHAR(15), bill_pin_id SMALLINT UNSIGNED, bill_addr VARCHAR(175), name VARCHAR(60), tel VARCHAR(15))
BEGIN
DECLARE em_id INT UNSIGNED;
DECLARE addr_id INT UNSIGNED;
DECLARE cust_id INT UNSIGNED;
DECLARE sql_error TINYINT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET sql_error = true;
-- check if customer email already exists
SELECT id INTO em_id FROM email_list WHERE email = email;
-- not sure of the return value, haven't tested it
IF em_id = 1 THEN
-- if emails exists check if customer exists
SELECT id INTO cust_id FROM customer WHERE email_list_id = em_id;
IF cust_id = 1 THEN
-- customer must have address information
SELECT address_id INTO addr_id from customer_addr
INNER JOIN address on address_id = address.id
WHERE customer_id = cust_id and address = bill_addr;
END IF;
END IF;
START TRANSACTION;
IF (em_id = 0) THEN
-- if email doesn't exist, no customer no address - simple insert
INSERT INTO email_list (email, status) VALUES (email, status);
SELECT LAST_INSERT_ID() INTO em_id;
INSERT INTO customer (email_list_id, full_name, phone)
VALUES (em_id, name, tel);
SELECT LAST_INSERT_ID() INTO cust_id;
INSERT INTO address (pincode_id, address) VALUES (bill_pin_id, bill_addr);
SELECT LAST_INSERT_ID() INTO addr_id;
INSERT INTO customer_addr (address_id, customer_id)
VALUES (addr_id, cust_id);
ELSE
UPDATE email_list SET status = status where id = em_id;
UPDATE customer SET full_name = name, phone = tel WHERE id = cust_id;
UPDATE address SET pincode_id = bill_pin_id, address = bill_addr;
END IF;
IF sql_error = FALSE THEN
COMMIT;
SELECT 'SUCCESS';
ELSE
ROLLBACK;
SELECT 'FAILED';
END IF;
END
I figured this out by executing the entire procedure via mysql console
It accepted it without any errors. I then accessed the procedure from phpmyadmin routines tab and exported the statement.
The only difference i could find is this
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `addCustomer`(
IN `email` VARCHAR(60),
IN `status` VARCHAR(15),
IN `bill_pin_id` SMALLINT UNSIGNED,
IN `bill_addr` VARCHAR(175),
IN `name` VARCHAR(60),
IN `tel` VARCHAR(15)
)
-- regular procedure statements
END$$
DELIMITER ;
I had made some errors with not adding semicolons after if statements as pointed out by Domingo Sambo.
I deleted the procedure and tested it again adding it via phpmyadmin query box and its working perfectly.

i want to insert same record for status=0 for the below code in mysql. but my logic is not working.can any one suggest me

I want to insert same record for status=0. But my logic is not working in MySQL.
Please add more text over here...
This question is about a stored procedure. And the user didn't provide any info what so ever.
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_insert2`(
IN P_page_Id int(11) ,
IN P_LanguageCode char,
IN P_page_status int(11),
IN p_created_by int(11),
IN p_created_date datetime,
OUT P_return int)
BEGIN
DECLARE v_isRecordExisting int;
DECLARE v_flags int;
SELECT
COUNT(*)
INTO
v_isRecordExisting
FROM
tbl_cms_pages_languages2
WHERE
page_status in(0,1)
AND
page_id = p_page_Id
AND
languagecode = P_LanguageCode;
IF
v_isRecordExisting = 0
THEN
INSERT INTO tbl_cms_pages_languages2 (
page_Id,
LanguageCode,
page_status,
created_by,
created_date
)
VALUES(
P_page_Id,
P_LanguageCode,
P_page_status,
P_created_by,
p_created_date
);
SET
p_return = 0;
ELSE
SET
p_return = 2;
END IF;
END

Mysql Stored Proc not returning a VARCHAR out parameter

Below is my stored procedure. It works fine but my problem is I can't get the output parameter as VARCHAR.
The part where I'm having problem is the assignment of #curcName to the out parameter op_resultMessage
BEGIN
SET op_resultMessage = #curcName;
END;
Here's the Stored Procedure.
CREATE DEFINER=`root`#`localhost` PROCEDURE `addCurriculum`(
IN p_curcName varchar(100),
IN p_description TEXT,
IN p_yearLevel VARCHAR(50),
IN p_syStart INT,
IN p_syEnd INT,
IN p_creator VARCHAR(50),
OUT op_resultMessage VARCHAR(50))
BEGIN
DECLARE curcName VARCHAR(20) ;
IF EXISTS
(SELECT #curcName := `name`
FROM curriculum
WHERE
yearLevel = p_yearLevel
AND syStart = p_syStart
AND syEnd = p_syEnd )
THEN --
BEGIN
SET op_resultMessage = #curcName;
END;
ELSE
BEGIN
INSERT INTO curriculum(`name`, description, yearLevel, syStart, syEnd, creator)
VALUES(p_curcName,p_description,p_yearLevel,p_syStart,p_syEnd,p_creator);
END;
END IF;
END
I'm trying to return a message IF name EXISTS
So it should go something like
SET op_resultMessage = #curcName 'already uses the school year and year level you're trying to insert';
But I don't know how to properly concatenate and assign values. I'm still confused with := SET and = operators. I guess that's where I'm having problems with.
If I change the out parameter's type to an INT like
OUT op_resultMessage VARCHAR(50)
then assigns a number to op_resultMessage like SET op_resultMessage = 1;
It returns the number 1 as out parameter values. It just won't work with varchar.
So when I try to call the procedure
CALL `enrollmentdb`.`addCurriculum`
('Test Curriculum ','Test ','Grade 1',2015,2016,'jordan',#outputMsg);
SELECT #outputMsg; -- this doesn't return any value even if Grade 1, 2015 and 2016 exists
I'd appreciate any help. I actually just learned mysql recently.
Thanks.
drop procedure if exists addCurriculum;
delimiter $$
CREATE PROCEDURE `addCurriculum`(
IN p_curcName varchar(100),
IN p_description TEXT,
IN p_yearLevel VARCHAR(50),
IN p_syStart INT,
IN p_syEnd INT,
IN p_creator VARCHAR(50),
OUT op_resultMessage VARCHAR(50))
BEGIN
DECLARE curcName VARCHAR(20) ;
SELECT `name` into #curcName
FROM curriculum
WHERE
yearLevel = p_yearLevel
AND syStart = p_syStart
AND syEnd = p_syEnd
LIMIT 1;
-- Note change above. When selecting into a variable (or more than 1)
-- then 0 or 1 rows can come back max or an Error occurs
IF #curcName is not null then
SET op_resultMessage = #curcName;
ELSE
BEGIN
INSERT INTO curriculum(`name`, description, yearLevel, syStart, syEnd, creator)
VALUES(p_curcName,p_description,p_yearLevel,p_syStart,p_syEnd,p_creator);
END;
SET op_resultMessage = 'GEEZ I am right here'; -- Drew added this
END IF;
END$$
delimiter ;
Note the commentary in the stored procedure, especially the part of only 0 or 1 rows returning else an Error will occur with a select into var pattern. So LIMIT 1. That may or may not be the row you want (limit 1), but that is where it is at right now.

MySQL function definition - 'BEGIN' (begin) is not a valid input at this position

I typed this up in verbatim from a textbook on MySQL.
There's a red X denoting an error on the line BEGIN with the text 'BEGIN' (begin) is not a valid input at this position.
The database used is View Ridge Gallery. Is there any obvious issues with the code?
DROP FUNCTION IF EXISTS InsertCustomerAndInterests;
DELIMITER $$
CREATE FUNCTION InsertCustomerAndInterests
(
newLastName Char(25),
newFirstName Char(25),
newAreaCode Char(3),
newPhoneNumber Char(8),
newEmail Varchar(100),
newNationality Char(30)
)
BEGIN
DECLARE varRowCount Int;
DECLARE varArtistID Int;
DECLARE varCustomerID Int;
DECLARE done Int DEFAULT 0;
DECLARE AristCursor CURSOR FOR
SELECT AristID
FROM ARTIST
WHERE Nationality=newNationality;
DECLARE continue HANDLER FOR NOT FOUND SET done = 1;
#Check to see if Customer already exists in datebase
SELECT Count(*) INTO varRowCount
FROM CUSTOMER
WHERE LastName = newLastName
AND FirstName = newFirstName
AND AreaCode = newAreaCode
AND PhoneNumber = newPhoneNumber
AND Email = newEmail;
#IF (varRowCount > 0 ) THEN Customer already exists
IF (varRowCount > 0 )
THEN
ROLLBACK;
SELECT 'Customer already exists';
END IF;
#IF (varRowCount = 0 ) THEN Customer does not exist.
#Insert new Customer data
IF (varRowCount = 0)
THEN
INSERT INTO CUSTOMER (LastName, FirstName, AreaCode, PhoneNumber, Email)
VALUES (newLastName, newFirstName, newAreaCode, newPhoneNumber, newEmail);
#Get new CustomerID surrogate key value
SET varCustomerID = LAST_INSERT_ID();
#Create intersection record for each appropriate Arist.
OPEN AristCursor;
REPEAT
FETCH ArtistCursor INTO varArtistArtistID;
IF NOT done THEN
INSERT INTO CUSTOMER_ARTIST_INT (ArtistID, CustomerID)
VALUES (varArtistID, varCustomerID);
END IF;
UNTIL done END REPEAT;
CLOSE ArtistCursor;
SELECT 'New customer and artist interest data added to database.'
AS InsertCustomerAndInterestsResults;
END IF;
END
$$
DELIMITER ;
You need to add return type before begin and must return value from the function.
DELIMITER $$
DROP FUNCTION IF EXISTS `InsertCustomerAndInterests`$$
CREATE FUNCTION `InsertCustomerAndInterests`(
newLastName CHAR(25),
newFirstName CHAR(25),
newAreaCode CHAR(3),
newPhoneNumber CHAR(8),
newEmail VARCHAR(100),
newNationality CHAR(30)
) RETURNS INT(11) # you missed return type here.
BEGIN
DECLARE done INT DEFAULT 0;
RETURN done; # must match with return type
END$$
DELIMITER ;
Since all functions need a return value and return type, you are missing the RETURNS clause after declaring your parameters. See CREATE FUNCTION

update and insert action in stored procedure

Can you tell me what is the wrong? I want to have a stored procedure that can do both update and insert action.
CREATE PROCEDURE `save_user`(IN `sp_aliasName` VARCHAR(100),IN `sp_password` VARCHAR(100), IN `sp_sex` VARCHAR(100), IN `sp_age` INT(11), IN `sp_userGroup` VARCHAR(100),OUT `sp_number_of_user` INT)
BEGIN
DECLARE temp INT;
SELECT COUNT(user_id) INTO sp_number_of_user FROM user WHERE aliasName = sp_aliasname;
temp := sp_number_of_user;
IF temp > 0
THEN
UPDATE user SET aliasName=sp_aliasName,password=sp_password,sex=sp_sex,age=sp_age,userGroup=sp_userGroup
WHERE aliasName = sp_aliasname ;
ELSE
INSERT INTO user (aliasName,password,sex,age,userGroup)
values (sp_aliasName,sp_password,sp_sex,sp_age,sp_userGroup);
END IF;
END
I think your procedure should look like this -
CREATE PROCEDURE `save_user`(IN `sp_aliasName` VARCHAR(100),IN `sp_password` VARCHAR(100), IN `sp_sex` VARCHAR(100), IN `sp_age` INT(11), IN `sp_userGroup` VARCHAR(100),OUT `sp_number_of_user` INT)
BEGIN
DECLARE temp INT;
SELECT count(user_id) INTO sp_number_of_user FROM user WHERE aliasName = sp_aliasname;
SET temp := sp_number_of_user;
IF temp > 0 THEN
UPDATE user SET aliasName = sp_aliasName, password = sp_password, sex = sp_sex, age = sp_age, userGroup = sp_userGroup
WHERE aliasName = sp_aliasname;
ELSE
INSERT INTO user (aliasName, password, sex, age, userGroup) VALUES (sp_aliasName, sp_password, sp_sex, sp_age, sp_userGroup);
END IF;
END
I added:
INT type to OUT parameter
WHERE clause to UPDATE statement (check this condition)
Also, have a look at INSERT ... ON DUPLICATE KEY UPDATE command, it may do what you need.