CREATE PROCEDURE `checkAdminAccess`
(
IN accountID INT
)
BEGIN
DECLARE staffID INT;
#DECLARE num INT;
SELECT StaffID INTO staffID
FROM staff
WHERE AccountID = accountID
AND IsAdmin = 1;
SELECT staffID;
IF (staffID IS NULL) THEN
CALL raise(1356, 'Admin access required.');
END IF;
END;
For any input I get the staffID as NULL.
For example:
call checkAdminAccess(3); #returns null
call checkAdminAccess(6); #returns null
And my data is below:
INSERT INTO `staff` (`StaffID`,`AccountID`,`RoleID`,`ManagerID`,`IsAdmin`) VALUES (1,3,1,1,0);
INSERT INTO `staff` (`StaffID`,`AccountID`,`RoleID`,`ManagerID`,`IsAdmin`) VALUES (2,6,2,1,1);
Can someone tell me how to do select a value into a variable in Mysql?
The problem is that you check the return value of a procedure, which must be null, since a procedure does not return any value. It maximum returns a resultset.
Possible solutions:
Change the procedure to function, that returns the staffid.
Add an out parameter to the procedure and use that to retrieve the staffid. The above link also describes how to do this.
Related
I have just started to create a stored function this is my first time so I am having a few problems. Currently I call the function using SELECT test(); (test is the function name for now). I want to send a number to the function (username ID) and have the username returned.
I have this working by using SELECT test(1); 1 is the ID of a user in the table. This seems to work as the username is returned, but if I type in any number the same username is returned also.
BEGIN
DECLARE new_username VARCHAR(90);
SELECT `username` INTO new_username FROM `users` WHERE `ID` = ID;
return new_username;
END
I have set the paramter as ID int .
Am I right in thinking that the keyword INTO will put the value of the username into the variable new_username ? If I run it without the INTO I get the error:
Not allowed to return a result set from a function
Have I made any obvious mistakes in this, I hope I havent done it totally wrong. Thanks for any advice :).
Edit : I just added a few more rows into my table , I now get the error:
Result consisted of more than one row
Full sql version:
CREATE DEFINER=`elliotts`#`%` FUNCTION `test`(ID int)
RETURNS varchar(32) CHARSET latin1
BEGIN
DECLARE new_username VARCHAR(32);
SELECT `username`
INTO new_username
FROM `users`
WHERE `ID` = ID;
return new_username;
END
Use:
DROP FUNCTION IF EXISTS `example`.`test` $$
CREATE FUNCTION `example`.`test` (param INT) RETURNS VARCHAR(32)
BEGIN
DECLARE new_username VARCHAR(32);
SELECT `username`
INTO new_username
FROM `users`
WHERE `ID` = param;
RETURN COALESCE(new_username, 'Username not found');
END $$
Mind that the VARCHAR length of the RETURN value matches the variable, which should match the column length you want to return.
I created a Stored Procedure in MySQL to return some parameters from a SELECT, but doesn't work.
ever returns 0 in userID and otherID.
Someone can help me?
Thanks
DROP PROCEDURE IF EXISTS sp_XPTO;
DELIMITER ;;
CREATE PROCEDURE sp_XPTO(
OUT userID INT UNSIGNED,
OUT otherID INT UNSIGNED,
IN bookID INT UNSIGNED
)
BEGIN
SELECT userID=E.userID, otherID=E.otherID
FROM Exp as E
WHERE E.bookID = bookID;
END ;;
DELIMITER ;
UPDATED:
Sorry,
After I read a lot, I concluded that the error is in how I call the stored procedure, and Ravinder is correct.
Thanks
I am not sure if your intention is to check the existence of a value in database.
Because, your select statement is doing a comparison but not assignment.
SELECT userID=E.userID, otherID=E.otherID
With the above statement, you may be thinking that value of E.userID is assigned to the OUT parameter userID. But the syntax you used is wrong.
In the above statement, both of the expressions return a boolean. As userID value did not match with E.userID the comparison resulted a false and you saw a 0. And it was the same for the otherID variable.
To assign values to variables you have to use INTO instructional operator.
Example:
SELECT E.userID, E.otherID
INTO userID, otherID
Change your stored procedure as below:
DROP PROCEDURE IF EXISTS sp_XPTO;
DELIMITER //
CREATE PROCEDURE sp_XPTO(
OUT userID INT UNSIGNED,
OUT otherID INT UNSIGNED,
IN bookID INT UNSIGNED
)
BEGIN
SELECT E.userID, E.otherID
INTO userID, otherID
FROM Exp as E
WHERE E.bookID = bookID; -- <- there was a ')'. removed.
END;
//
DELIMITER ;
Call the procedure with desired parameters and read the out parameters.
call sp_XPTO( #userID, #otherID, 234 ); -- where book id is 234
select #userID, #otherID;
I am trying to write a Mysql Function to return a contactID if the record exists based on the parameters supplied, If the record is not present, I am adding the record and then returning the contactID of the new record.
But the function is throwing 1048error, Can you check and correct me if I went wrong in writing this.
DELIMITER $$
CREATE DEFINER=`root`#`%` FUNCTION `GetContactID`(accountNumber CHAR(45),UserID INT(11)) RETURNS char(1) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE ContactID INT DEFAULT 0;
SELECT ContactID INTO #ContactID FROM Contact WHERE AccountNumber = #accountNumber AND UserID = #UserID AND Status =1;
IF ContactID = 0 or ContactID is null THEN
INSERT INTO Contact(AccountNumber,UserID) VALUES (#accountNumber,#UserID);
SELECT ContactID INTO #ContactID FROM Contact WHERE AccountNumber = #accountNumber AND UserID = #UserID;
END IF;
RETURN ContactID;
END
Can someone help me where I went wrong.
Thanks
The problem results from mixing user variables, local variables and parameters.
#UserId is not the same as UserId - they are different variables.
UserId is also a name of column in the table.
User defined variables are wirtten as #var_name, are stored in the user session and can be used to pass values between differend stored routines that reference them, see this link for details: http://dev.mysql.com/doc/refman/5.7/en/user-variables.html
local variables are declared in stored routines using DECLARE keyword, their scope is local within the stored routine, see this link for details: http://dev.mysql.com/doc/refman/5.7/en/declare-local-variable.html
Parameters of function/procedure - they are declared in the procedure/function declaration, they are used to pass parameters to the stored routine from the caller, can be also used to return results from the routine to the caller (if declared as OUT or INOUT). Their scope is similar to local variables. For details see this link: http://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
Try this code:
DELIMITER $$
CREATE DEFINER=`root`#`%` FUNCTION `GetContactID`(p_accountNumber CHAR(45),p_UserID INT(11)) RETURNS char(1) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE v_ContactID INT DEFAULT 0;
SELECT ContactID INTO v_ContactID
FROM Contact
WHERE AccountNumber = p_accountNumber AND UserID = p_UserID AND Status =1;
IF v_ContactID = 0 or v_ContactID is null THEN
INSERT INTO Contact(AccountNumber,UserID)
VALUES (p_accountNumber,p_UserID);
SELECT ContactID INTO v_ContactID FROM Contact
WHERE AccountNumber = p_accountNumber AND UserID = p_UserID;
END IF;
RETURN v_ContactID;
END;
Notice that:
function parameters are declared with prefix p_
local variables are declared with prefix v_
the function doesn't use any user variables (prefixed by #)
These prefixes help to avoid ambiguity - we know that p_UserID is a parameter, v_UserId is a local variable, and UserID is a column name in the table (If we would use #UserId, we knew that this was the user variable).
I write a function like the following. the purpose of this function is to return the place of a student by some specific exam in a branch.
DELIMITER $$
CREATE FUNCTION `getMerit`( branch VARCHAR(50), totalMark DECIMAL(19,2), comaSeparetedExamIds VARCHAR(200) ) RETURNS INT(11)
BEGIN
SET #comaSeparetedExamIds=comaSeparetedExamIds;
SET #branch =branch;
SET #marks=totalMark;
SELECT #place=COUNT(*)+1
FROM (
SELECT SUM(m.marks) marks
FROM marksheet m, studentinfo s
WHERE exam_id IN (#comaSeparetedExamIds)
AND m.student_roll=s.roll_no
AND s.branch LIKE CONCAT(#branch,'%')
GROUP BY m.student_roll
) AS a
WHERE a.marks>#totalMark;
RETURN #place;
END$$
DELIMITER ;
But It shows me an error. the Error is
Query : CREATE FUNCTION getMerit( branch varchar(50), totalMark
DECIMAL(19,2), comaSeparetedExamIds varchar(200) ) RETURNS int(11)
BEG... Error Code : 1415 Not allowed to return a result set from a
function
What mistake I made here, Can anyone please help me?
You can't name input variables with #. # is used for user variables, ie connection local variables that don't needs to be declared.
Also you can't have selects in functions.
Procedures can return result sets but return values.
Functions can return values but not result sets.
They also differs in how you use them.
select function_name(1) from dual;
select id, name, funcation_name(id, name) from anyTable;
call procedure_name(1);
And when assigning variables inside selects you need to do := and not =. In your code you are actually selecting true or false and not the count.
This should work.
DELIMITER $$
CREATE FUNCTION `getMerit`( branch VARCHAR(50), totalMark DECIMAL(19,2), comaSeparetedExamIds VARCHAR(200) ) RETURNS INT(11)
BEGIN
SET #comaSeparetedExamIds=comaSeparetedExamIds;
SET #branch =branch;
SET #marks=totalMark;
SELECT COUNT(*)+1 INTO #place
FROM (
SELECT SUM(m.marks) marks
FROM marksheet m, studentinfo s
WHERE exam_id IN (#comaSeparetedExamIds)
AND m.student_roll=s.roll_no
AND s.branch LIKE CONCAT(#branch,'%')
GROUP BY m.student_roll
) AS a
WHERE a.marks>#totalMark;
RETURN #place;
END$$
DELIMITER ;
I have a table Processes, which consists of an ID (unsigned int, auto_increment) and Name (varchar, unique).
Selecting the following function with any input (whether in the table or not) always results in
ERROR 1172 (42000): Result consisted of more than one row
CREATE FUNCTION LookupOrInsertProcess(nametwo VARCHAR(255))
RETURNS INT UNSIGNED
BEGIN
DECLARE myid INT UNSIGNED;
SELECT ID INTO myid FROM Processes WHERE Name=nametwo;
RETURN myid;
END$$
However, selecting the below function always returns NULL:
CREATE FUNCTION LookupOrInsertProcess(nametwo VARCHAR(255))
RETURNS INT UNSIGNED
BEGIN
DECLARE myid INT UNSIGNED;
SELECT ID INTO myid FROM Processes WHERE Name=nametwo;
RETURN myid;
END$$
Furthermore, please note that the following does return the correct result (numbers 30 and 50 are arbitrary):
CREATE FUNCTION LookupOrInsertProcess(nametwo VARCHAR(255))
RETURNS INT UNSIGNED
BEGIN
DECLARE myid INT UNSIGNED;
SELECT ID INTO myid FROM Processes WHERE Name=nametwo;
IF myid IS NULL THEN
RETURN 30;
ELSE
RETURN 50;
END IF;
END$$
Any help is appreciated.
UPDATE: Edited to remove clash between table column and function param. I don't believe that's the issue.
UPDATE2: Please note that the following appears to work, both when the input param is or is not in the table. Why, without the coalesce(), does the function return NULL even for input params which are in the table?
CREATE FUNCTION LookupOrInsertProcess(nametwo VARCHAR(255))
RETURNS INT UNSIGNED
BEGIN
DECLARE myid INT UNSIGNED;
SELECT ID INTO myid FROM Processes WHERE Name=nametwo;
RETURN COALESCE(myid, 0);
END$$
Column names are not case-sensitive in MySql so you may find that where Name = name means 'give me every row'.
Try changing the input parameter to your procedure (and the corresponding condition in the query) to be srchName or something else different to name.
Try to rename input name to different name like inputName.
Update:
Another suggestion.
DECLARE myid INT UNSIGNED;
SET myid = (SELECT ID FROM Processes WHERE Name=nametwo);
RETURN myid;