MySQL: call procedure from function - mysql

Is it possible to call a procedure from a function in MySQL? I get the error "not allowed to return a result set from a function." I want the results of the procedure call to be inserted into the function variables the same as if I had done a SELECT INTO directly in the function.
The function is (simplified) defined as
create function my_function()
returns int deterministic
begin
declare some_parameter int;
declare the_result int;
call my_procedure(some_parameter, the_result)
return the_result;
end;
The procedure is (simplified) defined as:
create procedure my_procedure(in my_parameter int, out my_result int)
begin
select 1
from dual;
end;

In essence, no. Functions are looking for a datatype, not a record (which is what is returned from the procedure).

Related

Trouble with calling a stored procedure within an stored procedure and setting result as a variable

I'm trying to call a stored procedure from another stored procedure and store the value in a variable. The inner stored procedure basically checks if something exists and uses a select statement to return a zero or one. I keep getting an error. In this situation, MySQL is saying "=" is not valid at this position, expecting ";"
CREATE PROCEDURE `CardNames_Add` (searchedCard VARCHAR(50))
BEGIN
DECLARE exist TINYINT;
EXECUTE exist = CardNames_CheckExist searchedCard
IF (exist = 0)
INSERT INTO card_names (name)
VALUE(searchedCard)
END
You have to rewrite you other stored procedure, that you don't need btw, to give back a result
CREATE PROCEDURE CardNames_CheckExist (IN searchedCard VARCHAR(50), OUT result TINYINT )
BEGIN
--do some stuzff
result = 1
END
CREATE PROCEDURE `CardNames_Add` (searchedCard VARCHAR(50))
BEGIN
CALL CardNames_CheckExist(searchedCard,#result);
IF (#result = 0) THEN
INSERT INTO card_names (name)
VALUES (searchedCard);
END IF;
END

MySQL ERROR #1415 - Not allowed to return a result set from a function

My question is about a function returning only one value but I still get this error, so What I'm supposed to get is average day between the order date and the shipped date, the query is doing that and returning me only one value which is the average. If I use just the SELECT statement outside the of the function I get one column/row answer of 8.4920.
How can I fix that please. Thanks.
DELIMITER //
DROP FUNCTION IF EXISTS OrderFulfilmel//
CREATE FUNCTION OrderFulfilmel(average int) RETURNS DOUBLE Deterministic
BEGIN
SELECT AVG(DATEDIFF(ShippedDate, OrderDate)) AS averageDay
FROM Orders;
END//
DELIMITER ;
You can try below
CREATE FUNCTION OrderFulfilmel(average int) RETURNS DOUBLE Deterministic
BEGIN
DECLARE var_name DECIMAL(10,2);
SET var_name = 0;
SELECT AVG(DATEDIFF(ShippedDate, OrderDate)) INTO var_name
FROM Orders;
RETURN var_name;
END
I don't understand why your function would have an argument. So, I'm thinking:
DELIMITER //
DROP FUNCTION IF EXISTS OrderFulfilmel//
CREATE FUNCTION OrderFulfilmel ()
RETURNS DOUBLE Deterministic
BEGIN
DECLARE #diff DOUBLE;
SELECT #diff := AVG(DATEDIFF(ShippedDate, OrderDate)) AS averageDay
FROM Orders;
RETURN #diff;
END//
DELIMITER ;

MySQL procedure to PostgreSQL function

Migrating from MySQL to PostgreSQL.
DROP PROCEDURE IF EXISTS prepend;
DELIMITER $$
CREATE PROCEDURE prepend
(
IN inParam VARCHAR(255),
INOUT inOutParam INT
)
BEGIN
DECLARE z INT;
SET z = inOutParam + 1;
SET inOutParam = z;
SELECT inParam;
SELECT CONCAT('zyxw', inParam);
END;$$
DELIMITER ;
CALL prepend('abcdefg', #inOutParam);
The MySQL procedure call output is:
abcdefg
zyxwabcdefg
Verify the output here.
Here's the original MySQL code snippet.
The corresponding PostgreSQL function is not working. Please help.
DROP FUNCTION prepend;
CREATE OR REPLACE FUNCTION prepend
(
inParam VARCHAR,
INOUT inOutParam INT
)
AS $$
DECLARE z INT;
BEGIN
z := inOutParam + 1;
inOutParam := z;
SELECT inParam;
SELECT CONCAT('zyxw', inParam);
END; $$
LANGUAGE plpgsql;
SELECT prepend('abcdefg', 0);
PostgreSQL has not unbound queries - this technique is available on Sybase like databases (Sybase, MSSQL) and MySQL (MariaDB). Currently you can write function that can returns set of some values (tabular result) or returns scalar, composite or array (usual functions).
So most near design to your procedure is:
CREATE OR REPLACE FUNCTION prepend(inparam text)
RETURNS SETOF text AS $$
BEGIN
RETURN NEXT inparam;
RETURN NEXT 'zyxw' || inparam;
END;
$$ LANGUAGE plpgsql;
you can call this function with SELECT
SELECT * FROM prepend('abcdefg');
That is all what is possible. You cannot to set other out variables in this case.
This is common problem when you porting stored procedures from Sybase like systems that uses this technique to any other database (Postgres, Oracle, DB2, ...). The functionality of these systems cannot be mapped simply 1:1.
Because Postgres (plpgsql) has not unbounded queries support, then the syntax is prohibited.
BEGIN
SELECT 1;
END;
Has not sense there. Any result of plpgsql functions can be realized by using OUT variables or by using RETURN statement.

mysql stored procedure 2 IN Param from SELECT

I need to call a stored procedure that have 2 IN Param into a stored procedure and the 2 IN Param are returned from a SELECT
Ex
CREATE PROCEDURE 'xxxx'
BEGIN
....
CALL MyProcedure ((SELECT InParam1,InParam2 FROM Table WHERE Id=1),#Out1,#Out2);
....
END
You cannot pass a query to a stored procedure. Fetch the values into the local variables and use those in procedure call. Also, use local variables instead of user-defined variables as out-parameters.
The reason for using local variables is that the user-defined variables can inadvertently change when you call another procedure.
CREATE PROCEDURE 'xxxx'
BEGIN
declare v_in1 int;
declare v_in2 int;
declare v_out1 int;
declare v_out2 int;
select InParam1,InParam2 into v_in1, v_in2
FROM Table
WHERE Id=1;
CALL MyProcedure (v_in1, v_in2, v_out1, v_out2);
....
END

How to make use of variable on a function

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.