I am not a MYSQL developer, but just had to write some code. Please accept my apologies if I am doing anything silly in my code.
My need is to get a single row like select * from users where userID = 1 limit 1 and assign it to a variable and access columns for doing some calculation. Firstly, is this possible?
I have tried to go through step by step, that is why I wrote a simple function like below
DELIMITER $$
CREATE DEFINER=`user`#`%` FUNCTION `GetReportees`(userid VARCHAR(255)) RETURNS varchar(50) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE Var1 varchar(120);
DECLARE Var2 varchar(120);
Select #Var1=forename, #Var2=surname from company_users.users where userID = #userid limit 1;
return #Var1;
END
when I try to save this function, it says that ERROR 1415: Not allowed to return a result set from a function. But I clearly return a varchar variable.
Could anyone tell me what I am doing wrong? it should not be this much hard, I believe.
Many thanks
Regards
You should read the documentation on the difference between user-defined variables and local variables.
In your example, you have a parameter and 2 local variables, so you should use them like this:
DELIMITER $$
CREATE DEFINER=`user`#`%` FUNCTION `GetReportees`(p_userid VARCHAR(255))
RETURNS varchar(120) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE Var1 varchar(120);
DECLARE Var2 varchar(120);
Select forename, surname
into Var1,Var2
from company_users.users
where userID = p_userid
limit 1;
return Var1;
END
Related
I have an issue in my code where i took this : (ApliEMAIL int) in below code but when i execute function it return empty values because in table i took email filed as varchar.
When i write code with this (ApliEMAIL varchar) it does not create function and gives error.
DELIMITER $$
#DROP FUNCTION IF EXISTS `get_appli_name`$$
CREATE FUNCTION get_appli_name_by_email(ApliEMAIL int)
RETURNS VARCHAR(255)
BEGIN
DECLARE A_NAME VARCHAR(255) DEFAULT"";
SELECT apli_fname INTO A_NAME
FROM tbl_signup
WHERE apli_email = ApliEMAIL;
RETURN A_NAME;
END$$
DELIMITER ;
DELIMITER $$
#DROP FUNCTION IF EXISTS `get_appli_name`$$
CREATE FUNCTION get_appli_name_by_email(ApliEMAIL varchar)
RETURNS VARCHAR(255)
BEGIN
DECLARE A_NAME VARCHAR(255) DEFAULT"";
SELECT apli_fname INTO A_NAME
FROM tbl_signup
WHERE apli_email = ApliEMAIL;
RETURN A_NAME;
END$$
DELIMITER ;
I tested your function. I got this error.
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable)
By the way, in the future, when you are asking for help with an error, include the error message in your post. Help us to help you! Don't make us guess!
Read the documentation about READS SQL DATA here: https://dev.mysql.com/doc/refman/8.0/en/stored-programs-logging.html
So I added that option to your function:
CREATE FUNCTION get_appli_name_by_email(ApliEMAIL VARCHAR(255))
RETURNS VARCHAR(255)
READS SQL DATA
BEGIN
DECLARE A_NAME VARCHAR(255) DEFAULT"";
SELECT apli_fname INTO A_NAME
FROM tbl_signup
WHERE apli_email = ApliEMAIL;
RETURN A_NAME;
END$$
It works now:
mysql> select get_appli_name_by_email('thefrog#muppets.org');
+------------------------------------------------+
| get_appli_name_by_email('thefrog#muppets.org') |
+------------------------------------------------+
| Kermit |
+------------------------------------------------+
You are missing the length of the ApliEMAIL-parameter.
Insted of:
CREATE FUNCTION get_appli_name_by_email(ApliEMAIL varchar)
you should have:
CREATE FUNCTION get_appli_name_by_email(ApliEMAIL varchar(255))
..or whatever the length of ApliEMAIL is.
You must add deterministic or reads sql data flag.
DELIMITER $$
CREATE FUNCTION get_appli_name_by_email(ApliEMAIL varchar(50))
RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
RETURN ifnull((SELECT apli_fname FROM tbl_signup WHERE apli_email = ApliEMAIL LIMIT 1), '');
END$$
DELIMITER ;
Would like to know what is the error on this syntax since all the sample given is similar with the 1 i try to create
CREATE FUNCTION test(regionCode varchar(5)) RETURNS CHAR(50)
DETERMINISTIC
READ SQL DATA
BEGIN
DECLARE NAME_FOUND CHAR(50);
SELECT 'abc' into NAME_FOUND from dual;
RETURN NAME_FOUND;
END
Thanks for the help.
mysql Functin having only READS SQL DATA not READ SQL DATA,that is the mistake you have done in your function.Please find the link for more details:
https://dev.mysql.com/doc/refman/5.7/en/stored-programs-logging.html
READS SQL DATA explicitly tells to MySQL that the function will ONLY read data from databases, thus, it does not contain instructions that modify data, but it contains SQL instructions that read data (e.q. SELECT).
DELIMITER $$
CREATE FUNCTION test(regionCode varchar(5)) RETURNS CHAR(50)
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE NAME_FOUND CHAR(50);
SELECT 'abc' into NAME_FOUND from dual;
RETURN NAME_FOUND;
END
CREATE FUNCTION test(regionCode varchar(5)) RETURNS CHAR(50)
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE NAME_FOUND CHAR(50);
SELECT 'abc' into NAME_FOUND from dual;
RETURN NAME_FOUND;
END
TRY THIS QUERY
I need to make a stored function:
This is my code
SELECT count(Dominio) FROM Thogar WHERE DOMINIO='%'
I need to make a stored function where I will write a letter between (U,C,R) and the function will replace the % in the previous code with the selected letter.
How can I do it? Thanks!
Got it working
CREATE FUNCTION `Buscar`(`param` CHAR(1))
RETURNS INT
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE res INT;
SELECT count(Dominio) INTO res FROM Thogar WHERE DOMINIO=param;
RETURN res;
END
Call buscar('C')
This should work:
DROP FUNCTION IF EXISTS myFunc;
DELIMITER $$
CREATE FUNCTION myFunc(
param CHAR(1)
) RETURNS INT;
BEGIN
DECLARE res INT;
SELECT count(Dominio) INTO res FROM Thogar WHERE DOMINIO=param;
RETURN res;
END;
$$
DELIMITER ;
If You want to make stored function with only one sql query,
I don't see any normal reason for it.
It will not give You performance gain.
How about simplification?
You can create view:
CREATE VIEW v_dominio_counters AS
SELECT Dominio, count(Dominio) AS counter FROM Thogar GROUP BY Dominio
And then use it:
SELECT counter FROM v_dominio_counters WHERE Dominio = 'U' LIMIT 1;
It will always keep for You ready to use counters that is handy when You have huge table.
Basically i'm going to run this procedure anytime a student enrolls/drops a course.
I'm trying to set student_total = # of students in a course, then update that corresponding section with (student_total + 1) i'm having trouble finding good documentation for stored procedures. I'm getting an error on my Declare student_total int; line. What am i not doing correct?
DELIMITER $$
CREATE PROCEDURE `mydb`.`update_seats` (IN section_ID varchar(20))
BEGIN
SET #section_id=section_id;
DECLARE student_total int;
-- count the number of students in the course --
SET student_total = SELECT count(student_ID) from course
WHERE section_ID = #section_id;
Update Section SET students_enrolled = (student_total + 1)
WHERE section_ID = #section_id;
END
Problems
Error 1
From MySql documentation:
DECLARE is permitted only inside a BEGIN ... END compound statement and must be at its start, before any other statements.
So, you should move DECLARE... statement before the SET #section_id... statement.
Error 2
You are trying to select a value into a variable using invalid snytax! You should use SELECT ... INTO instead of SET ... = SELECT ... (which is invalid syntax).
Removing Redundancy
No need to assign parameter (section_ID) to a global variable (#section_ID). You can simply change the parameter name to avoid name collision with section.section_ID column.
Solution
DELIMITER ;;
CREATE PROCEDURE `update_seats` (IN p_section_ID VARCHAR(20))
BEGIN
DECLARE student_total INT;
SELECT count(student_ID)
INTO student_total
FROM course
WHERE section_ID = p_section_ID;
UPDATE section
SET students_enrolled = (student_total + 1)
WHERE section_ID = p_section_ID;
END;;
DELIMITER ;
You're using the command line tool, yes?
It would be helpful to know the error message you received but based off the code you posted I don't see where you reset the delimiter command after the BEGIN...END block.
Taken from http://dev.mysql.com/doc/refman/5.1/en/stored-programs-defining.html
I'm learning stored procedures/functions/triggers in MySQL this morning and I'm having some problems trying to use variable table and column names in queries.
DELIMITER |
USE R2R |
DROP FUNCTION IF EXISTS getCategoryName |
CREATE FUNCTION getCategoryName(LMID INT, levelNum INT)
RETURNS VARCHAR(255)
BEGIN
DECLARE levelName VARCHAR(255) DEFAULT makeLevelName(levelNum);
DECLARE levelID INT;
DECLARE levelNameID VARCHAR(255) DEFAULT CONCAT(levelName, 'ID');
DECLARE ret VARCHAR(255);
SELECT #levelNameID INTO levelID FROM LevelMaster WHERE id=LMID;
SELECT description INTO ret FROM #levelName WHERE id=levelID;
RETURN ret;
END;
|
DROP FUNCTION IF EXISTS makeLevelName |
CREATE FUNCTION makeLevelName(levelNum INT)
RETURNS VARCHAR(255)
BEGIN
DECLARE word VARCHAR(255);
DECLARE ret VARCHAR(255);
IF levelNum=2 THEN SET word='Two';
ELSEIF levelNum=3 THEN SET word='Three';
ELSEIF levelNum=4 THEN SET word='Four';
ELSEIF levelNum=5 THEN SET word='Five';
END IF;
SET ret=CONCAT('Level', word);
RETURN ret;
END;
|
SELECT getCategoryName(347, 2) |
It's the first function (getCategoryName) that's causing me the problems, I need the two variables marked with # to be the table/column names - these two lines:
SELECT #levelNameID INTO levelID FROM LevelMaster WHERE id=LMID;
SELECT description INTO ret FROM #levelName WHERE id=levelID;
I want to keep this function as a function rather than a procedure if possible, but would accept answers for a procedure if it's the only way.
Thanks for you help,
Richard
Use User/Global Vars for this along with PREPARE & EXECUTE:
SET #columnName='myColumn';
SET #tableName='myTable';
SET #whatEver='requiredValue';
SET #query=CONCAT('SELECT ', #columnName, ' FROM ', #tableName, ' WHERE Column=', #whatEver);
PREPARE QUERY FROM #QUERY;
EXECUTE QUERY;
Haven't tested this EXACT code but something along these lines will work. Also has to be inside a Procedure, cannot be used with a function or trigger, if anyone has a soloution for that then please post.