MySQL save results of EXECUTE in a variable? - mysql

How do I save the results of EXECUTE statement to a variable? Something like
SET a = (EXECUTE stmtl);

If you want to do this with a prepared statement, then you need to include the variable assignment in the original statement declaration.
If you want to use a stored routine it's easier. You can assign the return value of a stored function directly to a variable, and stored procedures support out parameters.
Examples:
Prepared Statement:
PREPARE square_stmt from 'select pow(?,2) into #outvar';
set #invar = 1;
execute square_stmt using #invar;
select #outvar;
+---------+
| #outvar |
+---------+
| 1 |
+---------+
DEALLOCATE PREPARE square_stmt;
Stored Function:
delimiter $$
create function square_func(p_input int) returns int
begin
return pow(p_input,2);
end $$
delimiter ;
set #outvar = square_func(2);
select #outvar;
+---------+
| #outvar |
+---------+
| 4 |
+---------+
Stored Procedure:
delimiter $$
create procedure square_proc(p_input int, p_output int)
begin
set p_output = pow(p_input,2);
end $$
delimiter ;
set #outvar = square_func(3);
call square_proc(2,#outvar);
select #outvar;
+---------+
| #outvar |
+---------+
| 9 |
+---------+

Related

Run different SQL statements using If Then with a variable

Trying to do something very simple. Using If/Then, is there a way to run a separate Select statement based on the value of a variable?
The function GetTotalActiveUnits() in the below code returns an integer.
set #RetVal = GetTotalActiveUnits(CustomerCode);
if #RetVal = 0 then
Select * from tblREF_UnitInfo;
else
select * from tblREF_State;
end if
There is no problem with your code - at least as far as IF is concerned and if it is in a stored routine.
drop procedure if exists p;
delimiter $$
create procedure p(inp int)
begin
set #RetVal = inp;# GetTotalActiveUnits(CustomerCode);
if #RetVal = 0 then
select #retval ;
else
select #retval ;
end if ;
end $$
delimiter ;
call p(1);
+---------+
| #retval |
+---------+
| 1 |
+---------+
1 row in set (0.001 sec)
call p(0)
+---------+
| #retval |
+---------+
| 0 |
+---------+
1 row in set (0.001 sec)

How to update table using execute statement?

I have two tables (much simplified here):
QUADRI
ID SBR_750 b10C TGI
---------------------
Q1 0 1 0
Q2 2 1 0
Q3 1 0 1
CELLE
CELLANAME NEEDED READY
----------------------
SBR_750 NULL 12
b10C NULL 10
TGI NULL 5
I want this result in CELLE:
CELLANAME NEEDED READY
------------------------
SBR_750 3 12
b10C 2 10
TGI 1 5
I tried to write a stored procedure but it doesn't works: ERROR 1210. Incorrect arguments to EXECUTE.
Here is the code:
CREATE DEFINER=`root`#`%.zamberlan.local` PROCEDURE `AggiornaCelle`(IN nomecella varchar(15))
BEGIN
set #s='update celle set needed=(select sum(?) from quadri) where cellaname=?';
set #NC=nomecella;
prepare stmt from #s;
execute stmt using #NC;
deallocate prepare stmt;
END
UPDATE:
It doesn't work so I change strategy:
CREATE DEFINER=`root`#`%.zamberlan.local` PROCEDURE `AggiornaCelle`()
BEGIN
declare i int;
declare num_rows int;
declare col_name varchar(20);
DECLARE col_names CURSOR FOR
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = quadri
ORDER BY ordinal_position;
select FOUND_ROWS() into num_rows;
SET i = 1;
the_loop: LOOP
IF i > num_rows THEN
CLOSE col_names;
LEAVE the_loop;
END IF;
FETCH col_names
INTO col_name;
update celle set needed=sum(col_name) where cellaname=col_name;
SET i = i + 1;
END LOOP the_loop;
END
inspired by mysql, iterate through column names.
However I receive the error "Cursor is not open..."
You do need to use dynamic sql to do this. Celle knows about all the columns it needs from quadri so you could drive the creation of the dynamic statements from this fact. Using a cursor is as good a way to do it as any.
drop table if exists quadri;
create table quadri(ID varchar(2),SBR_750 int, b10C int, TGI int);
insert into quadri values
('Q1' , 0 , 1 , 0),
('Q2' , 2 , 1 , 0),
('Q3' , 1 , 0 , 1);
drop table if exists celle;
create table CELLE (CELLANAME varchar(20) ,NEEDED int,READY int);
insert into celle values
('SBR_750' , NULL , 12),
('b10C' , NULL , 10),
('TGI' , NULL , 5);
drop procedure if exists `AggiornaCelle`;
delimiter $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `AggiornaCelle`()
begin
DECLARE done INT DEFAULT FALSE;
declare col_name varchar(20);
declare cur1 CURSOR FOR
SELECT cellaname FROM celle ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open cur1;
read_loop: loop
fetch cur1 into col_name;
if done then leave read_loop; end if;
set #sqlstr = concat('update celle set needed = (select sum(',col_name,') from quadri) where cellaname = ', char(39),col_name,char(39),';');
insert into debug_table (msg) values(#sqlstr);
prepare stmt from #sqlstr;
execute stmt ;
deallocate prepare stmt;
end loop;
close cur1;
end $$
delimiter ;
truncate table debug_table;
call `AggiornaCelle`();
select * from debug_table;
select * from celle;
MariaDB [sandbox]> select * from debug_table;
+----+------------------------------------------------------------------------------------------+------+
| id | msg | MSG2 |
+----+------------------------------------------------------------------------------------------+------+
| 1 | update celle set needed = (select sum(SBR_750) from quadri) where cellaname = 'SBR_750'; | NULL |
| 2 | update celle set needed = (select sum(b10C) from quadri) where cellaname = 'b10C'; | NULL |
| 3 | update celle set needed = (select sum(TGI) from quadri) where cellaname = 'TGI'; | NULL |
+----+------------------------------------------------------------------------------------------+------+
3 rows in set (0.00 sec)
MariaDB [sandbox]> select * from celle;
+-----------+--------+-------+
| CELLANAME | NEEDED | READY |
+-----------+--------+-------+
| SBR_750 | 3 | 12 |
| b10C | 2 | 10 |
| TGI | 1 | 5 |
+-----------+--------+-------+
3 rows in set (0.00 sec)
The debug_table only exists so that I can check the update statements.
As per documentation
set #s='update celle set needed=(select sum(?) from quadri) where cellaname=?';
You are supposed to pass two argument.
execute stmt using #NC;
should be or something similar
execute stmt using #NC, #NC;
#NC would be same as you are trying to update a row in celle, which is same as column name in quadri table.

How to call stored procedure and select the return value at a time on MySQL

on MySQL, I know I can use stored procedure something like this
call someProcedure(#return);
select #return;
but is there some way you can do it with single query ? like this
select #return from (call someProcedure(#return) as sp
thanks in advance :)
Define Procedure
mysql> DELIMITER //
mysql> CREATE PROCEDURE simpleproc(OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END //
call the procedure ->
mysql> CALL simpleproc(#a);
Show Output ->
mysql> SELECT #a;
+------+
| #a |
+------+
| 3 |
+------+1 row in set (0.00 sec)

Inserting to selected table name

I have got a table called Aliases in my MySQL database.
Looks like this:
------------------
| Id | Alias |
------------------
|1 | 'TabX' |
------------------
|2 | 'TabY' |
...
| | |
------------------
And I need to insert to those tables like this:
INSERT INTO (SELECT Alias FROM Aliases WHERE id=1) (somevalue) VALUES (value);
This doesn't work. Please help.
You can reach it with prepared statements:
SET #alias = (SELECT Alias FROM Aliases WHERE id = 1);
SET #sql = CONCAT('INSERT INTO ', #alias, ' (somevalue) VALUES (value)');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
You need to make PROCEDURE for that. And use prepared statements for this purpose. You need procedure like that:
DELIMITER $$
DROP PROCEDURE IF EXISTS `DB`.`INSERT_VAR`$$
CREATE DEFINER=`user`#`host` PROCEDURE INSERT_VAR(IN tableName VARCHAR(200))
BEGIN
SET #insert_query=CONCAT("INSERT INTO ", tableName, " (id) SELECT id FROM test");
PREPARE stmtInsert FROM #insertTab;
EXECUTE stmtInsert;
END$$
DELIMITER ;
You need to modify this procedure to fit your needs.
Try this
INSERT INTO table_name
SELECT Alias
FROM Aliases
WHERE id = 1

Get current executing stored procedure name in MySQL?

I need a log for the stored procedures i have written in MySQL.
I know this is available in MS SQL Server as ##procid.
What is the equivalent in MySQL?
I'm going to use a timestamp, connection_id, database().
How can i get the name of the sp i am executing?
How about the sp that called me?
thanks,
adam
You can pass a procedure name as an IN parameter into called procedures, and log this information from these procedures.
For example -
DELIMITER $$
CREATE PROCEDURE procedure1(IN proc_name VARCHAR(255))
BEGIN
INSERT INTO proc_log VALUES('procedure1', proc_name, NOW());
END$$
CREATE PROCEDURE procedure2(IN proc_name VARCHAR(255))
BEGIN
INSERT INTO proc_log VALUES('procedure2', proc_name, NOW());
CALL procedure1('procedure2');
END$$
DELIMITER ;
CALL procedure2(NULL);
SELECT * FROM proc_log;
+------------+----------------+---------------------+
| proc_name | call_proc_name | call_ts |
+------------+----------------+---------------------+
| procedure2 | NULL | 2012-07-30 16:17:53 |
| procedure1 | procedure2 | 2012-07-30 16:17:53 |
+------------+----------------+---------------------+