If I have a TABLE named MyTable which has columns say C1(type date) and C2 (type character) I want to create a stored function that takes an input and the input should always belong to C1, and the output of the stored function should be the corresponding element in C2. I have tried to do it using the 'select' statement followed by 'where' clause inside the stored function but was not able to achieve it. Is there any other way to accomplish this task.
DELIMITER $$
CREATE FUNCTION `MyFunction`
(`Date` datetime)
RETURNS char(10)
BEGIN
DECLARE MyVariable char(10)
SELECT MyVariable = `C2`
FROM MyTable
WHERE `Date` = `C1`; RETURN MyVariable;
END$$
DELIMITER ;
But this keeps giving me ERROR CODE: 1064
At first glance, I see a syntax error:
...
BEGIN
DECLARE MyVariable char(10) <-- needs a semicolon here
SELECT MyVariable = `C2`
...
Every statement within the body of your routine must end with a semicolon. See examples of DECLARE in this manual page: https://dev.mysql.com/doc/refman/8.0/en/local-variable-scope.html
It should be like this:
...
BEGIN
DECLARE MyVariable char(10);
SELECT MyVariable = `C2`
...
Re your comment:
Error 1415 means "cannot return a result set". Your stored function is doing a SELECT without putting the result into your declared local variable using an INTO keyword.
You appear to be trying to set the value of MyVariable using = but that's just making a comparison. It doesn't assign anything to MyVariable.
Without using INTO to assign the variable, your SELECT statement is by default returning a result set. This is allowed in a stored procedure, but not in a stored function. A stored function must return a single scalar value, not a result set.
...
BEGIN
DECLARE MyVariable char(10);
SELECT `C2` INTO MyVariable
FROM MyTable
WHERE `Date` = `C1`;
RETURN MyVariable;
END
P.S.: I edited your question to replace the term "user-defined function" with "stored function". These are two different things in MySQL. You are writing a stored function.
In MySQL, they use the term user-defined function (UDF) for a function you implement in C/C++ code and compile into the MySQL server. It's less common for developers to write this type of extension.
Related
I am getting this error message
RETURN statements in scalar valued functions must include an argument
when run this query:
create function gender(#gender nvarchar(40))
returns nvarchar(40)
as
begin
(select name,cast(DOB as date) as DOB from datenames where gender = #gender)
return
end
The write way to create a function in mysql for your example is as follows:
DELIMITER \\
create function gender(Igender nvarchar(40))
returns nvarchar(40)
begin
DECLARE customerLevel NVARCHAR(40);
IF EXISTS (select name,cast(DOB as date) as DOB from datenames where gender = Igender) THEN
SET customerLevel = 'SOMETHING1';
ELSE
SET customerLevel = 'SOMETHING2';
END IF;
RETURN (customerLevel);
end
No need to as
No need to # before input
You need to return something.
Don't forget to use DELIMITER.
If you use phpmyadmin and has problem with nvarchar read this post: Unrecognize data type nvarchar in database or simply change it to to varchar.
DELIMITER //
CREATE PROC InserimentoValori()
BEGIN
DECLARE #caratteri varchar(30);
set #caratteri = 'abcdefghijklmnopqrstuvwxyz',
DECLARE x INT DEFAULT 1;
WHILE x <=100 DO
INSERT INTO Persona(nome,cognome,eta) VALUES((SELECT #caratteri = substring(#caratteri +1),(SELECT #caratteri = sebstring(#caratteri +1),(SELECT floor(rand() * 99) AS randNum));
SET x = x+1;
END WHILE
END //
DELIMITER ;
I want to create a stored procedure that insert random values into the table.
Thanks
There are a couple of errors.
We don't "declare" user defined variables in MySQL. Just SET them.
If you want to DECLARE a variable within a procedure, that needs to be a procedure variable.
A user defined variable has a name that starts with the # character. A procedure variable cannot start with a # character.
So, a line like this is an error:
DECLARE #foo ...
If you want to use a user defined variable, remove that line. If you want to use a procedure variable, remove the # from the beginning of the variable name (and make that same change everywhere you want to reference the procedure variable foo.)
And SEBSTRING is not the name of a MySQL provided function.
Also, a boolean expression in a SELECT list of a query will return 0, 1 or NULL.
For example:
SELECT #caratteri = substring(#caratteri +1)
That expression is comparing the value on the left side of the = with the value on the right, and is going to return 1 if they are equal, or 0 if the aren't, or NULL if either of the values is NULL.
To perform an assignment to a user defined variable in a SELECT statement, use the Pascal-style := operator.
(If you meant to do an assignment, the design makes it look like you are gogin to lop off the first character each time through the loop; that's eventually going to be an empty string, if we loop enough times. You may want to think about leaving the string static. Consider incrementing integer values, and use those as arguments in SUBSTRING function. And you can use the MOD operator to get the integer value to "wrap".)
I am trying to have a conditional change in a parameter for update statement.
I am getting the following error when I try the following function
/home/y/bin/mysql -u root < testpri.sql > out
ERROR 1415 (0A000) at line 4: Not allowed to return a result set from a function
Contents of testpri.sql are as follows:
use `zestdb`;
DROP FUNCTION IF EXISTS UPDATEPASSWD;
DELIMITER //
CREATE FUNCTION UPDATEPASSWD(n INT) RETURNS varchar(255) DETERMINISTIC
BEGIN
DECLARE mypasswd varchar(255);
IF (n = 1) THEN
SET mypasswd = '12ccc1e5c3c9203af7752f937fca4ea6263f07a5';
SELECT 'n is 1' AS ' ';
ELSE
SET mypasswd = '1a7bc371cc108075cf8115918547c3019bf97e5d';
SELECT 'n is 0' AS ' ';
END IF;>
SELECT CONCAT('mypasswd is ', mypasswd) AS ' ';
RETURN mypasswd;
END //
DELIMITER ;
CALL UPDATEPASSWD(0);
What am I missing?
I think it's actually your debugging SELECT calls.
From the docs:
Statements that return a result set can be used within a stored procedure but not within a stored function. This prohibition includes SELECT statements that do not have an INTO var_list clause...
I arrived in search of answers to the same question, and found another way to work around the issue, so that I can use the SELECT statement that is the heart and soul of the MySQL function that elicited the warning.
Consider the following snippet.
SET intNMatches = ( SELECT COUNT(*) ...
SET coerces the SELECT statement to return its one and only column, a row count, into intNMatches, a local variable cast to BIGINT. Since it contains trade secrets, I can't show the rest of the query. Suffice it to say that the query installs without causing the MySQL engine to issue a warning.
Does anybody know if this is allowed?
IF CALL GET_RIGHT_NODE(edge) = 15
THEN
SELECT "IT WORKS";
I'm getting an error on this syntax, is it possible any other way?
The return values from stored procedures should be captured in OUT paramters (whereas those from user defined functions can be captured as #returnValue = function()).
So, your GET_RIGHT_NODE should take an OUT parameter and set it to the return value.
CREATE PROCEDURE GET_RIGHT_NODE
(
#edge INT,
#returnValue INT OUTPUT
)
AS
-- Definition of the proc.
then you would call the procedure as follows:
DECLARE #returnValue INT
CALL GET_RIGHT_NODE(#edge, #returnValue)
IF (#returnValue = 15)
THEN
SELECT 'IT WORKS'
I am using a pl/pgsql function that uses custom_variable_class, the function code is
CREATE OR REPLACE FUNCTION can_connect("pUserId" character varying)
RETURNS boolean AS
$BODY$DECLARE
user_id integer ;
BEGIN
SELECT users.user_serial INTO user_id
FROM public.users
WHERE users.user_id="pUserId"
;
set public.userId to user_id ;
set public.companyId to "pUserId" ;
RETURN true ;
EXCEPTION
WHEN OTHERS THEN
raise notice ' error %',sqlerrm ;
END ;
$BODY$
LANGUAGE plpgsql VOLATILE
Now using the function
select can_connect ('amr' );
t
it's ok, the return value is t as expected.
But when trying to retrive the session variable values
select current_setting('public.userId') ;
the result is
user_id
Which is variable name not the value
the same thing when using the function argument
select current_setting('public.pUserId') ;
the result is
pUserId
Thank you.
Use plpgsql EXECUTE to force the parser to interpolate the values of the variables:
EXECUTE 'set public.userId to ' || quote_literal(user_id);
EXECUTE 'set public.companyId to ' || quote_literal( "pUserId");
As a bonus it will also work with older versions of PostgreSQL.
It is allowed to SET only PostgreSQL's configuration parameters this way.
On PostgreSQL 9.1 I have the following output:
SET user_id TO bbb;
ERROR: unrecognized configuration parameter "user_id"
As PostgreSQL has no packages, the best way to keep state is to use temporary tables.