Mysql Function returns Null always - mysql

I have a function in mysql like below:
DELIMITER $$
CREATE DEFINER=root#localhost FUNCTION fnGetDropDownValue(
itemValue varchar(300),
DropDownId int,
CId int
) RETURNS int(11)
BEGIN
DECLARE listId int;
SELECT ListID into listId FROM DropDownListValues WHERE LOWER(ListValue) = LOWER(itemValue) AND DropDownListID = DropDownId AND (ClientId = 0 OR ClientId = CId);
RETURN listId;
END$$
But it always returns Null values when I use
SELECT fnGetDropDownValue('General', 24, 18);
I don't know what I am doing wrong :(

After having the case sensitive issue with mysql columns I used to have variable names to start with _ to avoid it messing with column names. Now the stored procedure looks like this:
DELIMITER $$
CREATE DEFINER=root#localhost FUNCTION fnGetDropDownValue(
itemValue varchar(300),
DropDownId int,
CId int
) RETURNS int(11)
BEGIN
DECLARE _listId int;
SELECT ListID into _listId FROM DropDownListValues WHERE LOWER(ListValue) = LOWER(itemValue)
AND DropDownListID = DropDownId AND (ClientId = 0 OR ClientId = CId);
RETURN _listId;
END$$
This way it will work on any platform and it may be useful for others.

Related

Stored Procedure updates two rows

DELIMITER //
CREATE OR REPLACE PROCEDURE GET_USER_PNTS(USER_ID INT , PNTS INT, QNT INT)
BEGIN
DECLARE x INT DEFAULT 1;
DECLARE TEMP_GIFT_ID INT;
UPDATE USR_PNT_SUMM SET USD_PNTS = USD_PNTS + PNTS WHERE USER_ID = 1;
COMMIT;
END //
DELIMITER ;
The above stored procedure updates two rows - one for user_id = 1 and the other one for userid 0. I dont understand why!
This is how I call the stored procedure -
CALL GET_USER_PNTS(1, 1, 1)
Please let me know why the user_id 0 is also getting updated.
P.S
1. I am using MariaDB.
2. UserID 0 is what I had manually added in the table. In pratice there won't be any 0 user_id. But even then, the row should not have been updated.
Please rename your parameters:
CREATE OR REPLACE PROCEDURE GET_USER_PNTS(L_USER_ID INT , L_PNTS INT, L_QNT INT)
BEGIN
DECLARE x INT DEFAULT 1;
DECLARE TEMP_GIFT_ID INT;
UPDATE USR_PNT_SUMM SET USD_PNTS = USD_PNTS + L_PNTS WHERE USER_ID = L_USER_ID;
COMMIT;
END //
Probably USER_ID = USER_ID is treated as true.

Pass the columns of each row in a result set to a stored function in single step

The following is my stored function
DELIMITER $$;
CREATE FUNCTION set_credit_values (emp_id bigint, lpc_id int, elc_date date) RETURNS date DETERMINISTIC
BEGIN
SELECT do_credit(emp_id, lpc_id, elc_date,ltp_id, lpb_cr_count, lpb_cr_on, lpb_next_cr, lpb_cr_period)
FROM erp_leave_policy_body,erp_leave_type
WHERE lpb_fk_leave_policy = lpc_id AND ltp_id = lpb_fk_leave_type AND ltp_status=1;
RETURN elc_date;
END $$;
DELIMITER ;
I need to pass the selected values in each row in the result set (by the SELECT query) to do_credit() function. But it is showing errors as
#1415 - Not allowed to return a result set from a function
The do_credit() function is as
DELIMITER $$;
CREATE FUNCTION do_credit (emp_id bigint, lpc_id int, new_elc_date date,ltp_id int, cr_count tinyint, cr_on tinyint, next_cr date, cr_period tinyint)
RETURNS boolean DETERMINISTIC
BEGIN
DECLARE next_credit_date DATE DEFAULT NULL;
DECLARE is_credited INT(11) DEFAULT 0;
SET next_credit_date = get_next_credit(emp_id, lpc_id, new_elc_date,ltp_id, cr_on, next_cr, cr_period);
IF next_credit_date = new_elc_date THEN
SELECT COUNT(*) INTO is_credited FROM erp_employee_leave_credits WHERE
elc_fk_employees = emp_id AND elc_fk_leave_policy = lpc_id AND elc_fk_leave_type = ltp_id AND elc_date = new_elc_date;
-- If the leave is not credited yet
IF is_credited = 0 THEN
INSERT INTO erp_employee_leave_credits(elc_fk_employees,elc_fk_leave_policy,elc_fk_leave_type,elc_date,elc_cr_count) VALUES (emp_id,lpc_id,ltp_id,new_elc_date,cr_count);
END IF;
END IF;
RETURN 1;
END $$;
DELIMITER ;
It is working successfully.
I know using cursor. But when using cursor I should traverse through each row in the result set. So may take more time. If I call the function with the select query it works faster than cursor. So How can solve this error.

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

Procedures always returns empty results

I cant get this code to return me anything, i used to have the code in 2 functions and it always returned a random first name and a random last name but ever since i tried putting the code into this procedure it doesnt return anything, either empty results or just nothing happens after submitting the CALL command
DROP PROCEDURE IF EXISTS IdGenerator;
DELIMITER $$
CREATE PROCEDURE IdGenerator(tempCntry varchar(255))
BEGIN
DECLARE rndm1 INT;
DECLARE rndm2 INT;
DECLARE rndmPlier INT;
DECLARE firstN varchar(255);
DECLARE lastN varchar(255);
DROP TABLE IF EXISTS pplGrp;
CREATE TEMPORARY TABLE pplGrp(FirstName_tmp varchar(255), LastName_tmp varchar(255));
SELECT MAX(ChancesEnd) INTO rndmPlier FROM personlist WHERE country = tempCntry;
SET rndm1 = FLOOR((1+RAND() * (rndmPlier-1)));
SELECT p.name INTO firstN FROM personlist p WHERE country = tempCntry AND FirstName = 1 AND sex = 0 AND p.ChancesStart <= rndm1 AND p.ChancesEnd >= rndm1 LIMIT 1;
SET rndm2 = FLOOR((1+RAND() * (rndmPlier-1)));
SELECT p.name INTO lastN FROM personlist p WHERE country = tempCntry AND LastName = 1 AND sex = 0 AND p.ChancesStart <= rndm2 AND p.ChancesEnd >= rndm2 LIMIT 1;
INSERT INTO pplGrp (FirstName_tmp, LastName_tmp)values(firstN, lastN);
SELECT * FROM pplGrp;
END$$
DELIMITER ;