Using dynamic SQL in MySql function - mysql

I have created a function in phpMyAdmin as shown in this screenshot.
When I try to use it like this:
Select DMax ("id","customers")
I get error #1305 saying that uTable does not exist. This is probably some basic syntax issue, as uTable in the sql statement is taken literally and not seen as a parameter. So how do I make it work?

You can't use parameters to a procedure for column or table names. Instead, you need to prepare a statement using those values and execute that. For example:
BEGIN
DECLARE uValue INT(11);
SET #sql = CONCAT('SELECT MAX(', uField, ') INTO uValue FROM ', uTable);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
RETURN uValue;
END
Note that you cannot use dynamic SQL in a function, so you would need to convert this into a stored procedure with uValue an OUT parameter i.e.
CREATE PROCEDURE DMax(
IN uField VARCHAR(100),
IN uTable VARCHAR(100),
OUT uValue <appropriate type>
)
BEGIN
DECLARE uValue INT(11);
SET #sql = CONCAT('SELECT MAX(', uField, ') INTO uValue FROM ', uTable);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Then you would need to call the procedure, something like
CALL DMax('table1', 'column1', #DMax)
and you can then
SELECT #DMax
(yes, this is a monumental pain)

Related

How Do I Use Dynamic SQL (MySQL) To Store The Result of a Query Into a Local Variable?

In the procedure I'm writing I need to store the result of a dynamic SQL query into a local variable. Something like this:
DELIMITER //
CREATE PROCEDURE test_maxsum(uid varchar(25))
BEGIN
DECLARE maxsum int;
SET #SQL = CONCAT('SELECT MAX(sum_val) FROM ', uid);
PREPARE stmt FROM #SQL;
EXECUTE stmt INTO maxsum;
DEALLOCATE PREPARE stmt;
SELECT maxsum;
END//
DELIMITER ;
Local variables cannot be assigned in prepared statements. You can use user-defined variables though:
DELIMITER //
CREATE PROCEDURE test_maxsum(uid varchar(25))
BEGIN
SET #SQL = CONCAT('SELECT MAX(sum_val) INTO #maxsum FROM ', uid);
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SELECT #maxsum;
END//
DELIMITER ;

mysql prepared statment giving error

i am trying to write a stored procedure which updates the field of a table as specified in the argument .i am getting syntax error in #sql statment.please help
create procedure new_upd1(ind int(3),attribute varchar(30),pk int(11),new_value varchar(30))
begin
set #att=attribute;
set #primk=pk;
set #updated=new_value;
if ind=1 then
set #sql='update department set ?=? where departmentid=?';
prepare stmt from #sql;
execute stmt using #att,#updated,#primk;
deallocate prepare stmt;
end if;
end
Parameters don't work for column or table names, only for values. Do it like this:
create procedure new_upd1(ind int(3),attribute varchar(30),pk int(11),new_value varchar(30))
begin
set #att=attribute;
set #primk=pk;
set #updated=new_value;
if ind=1 then
set #sql=CONCAT('update department set ', #att, '=? where departmentid=?;');
prepare stmt from #sql;
execute stmt using #updated,#primk;
deallocate prepare stmt;
end if;
end

Stored procedure output variable

I am trying to run a procedure that takes a parameter 'table' for the query, and result as the output parameter. However, it shows as undeclared variable: result
I have doubled checked that no spelling mistake but still have no idea how it happened. Would someone please provide some help or guidance
CREATE DEFINER=`root`#`localhost` PROCEDURE `Function`(IN table varchar(10), OUT result varchar (10))
BEGIN
SET #q = CONCAT ('
Select `field` from `',table,'` into result limit 1;');
PREPARE stmt from #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Try:
...
-- SET #q = CONCAT ('Select `field` from `',table,'` into result limit 1;');
SET #`q` := CONCAT('SELECT `der`.`field`
FROM (SELECT `field` FROM `', `table`, '` LIMIT 1) `der`,
(SELECT #`result` := NULL) `init`
INTO #`result`;');
PREPARE `stmt` from #`q`;
EXECUTE `stmt`;
SET `result` := #`result`;
DEALLOCATE PREPARE `stmt`;
...
It is important to indicate the difference between 9.4. User-Defined Variables and routine parameters 13.1.15. CREATE PROCEDURE and CREATE FUNCTION Syntax, are different variables.
SQL Fiddle demo

how to define a stored procedures which accepts 2 parameteres

I´m trying to define a stored procedures which accepts 2 parameteres , one would be the table column which has to be equal with the second parameter i will provide.
Code :
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `selectUserByField`(IN _field varchar(150) , IN _value varchar(150))
BEGIN
SET #sql = CONCAT('SELECT * FROM Users WHERE', _field, '=' ,_value);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
The thing is that i don´t know how to provide the _value param as a string. If i run it like this i get a Mysql 1064 near ´=myEmail´( params where ´userEmail´,´myEmail´). Thanks !
In your below code, you are missing a space after WHERE. It should be like below; give a space after WHERE and in =
SET #sql = CONCAT('SELECT * FROM Users WHERE ', _field, ' = ' ,_value);

MySQL How to get results after PREPARE and EXECUTE in Stored Procedure?

My current code is :
DELIMITER \\
CREATE PROCEDURE sample (IN _car VARCHAR(15))
BEGIN
DECLARE _a INTEGER;
SET #s = CONCAT('SELECT COUNT(*) FROM train WHERE ', _car, '<=0;');
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END\\
But I wanted to capture the answer of the SELECT statement to my _a variable.
I tried changing my code to
SET #s = CONCAT('SELECT COUNT(*) INTO', _a,' FROM train WHERE ', _car, '<=0;');
But that didn't work.
Help, please?
SOLVED!
DELIMITER \\
CREATE PROCEDURE sample (IN _car VARCHAR(15))
BEGIN
DECLARE _a INTEGER;
SET #var = NULL;
SET #s = CONCAT('SELECT COUNT(*) INTO #var FROM train WHERE ', _car, '<=0;');
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
SELECT #var;
DEALLOCATE PREPARE stmt1;
END\\
:D
As stated here you need to include the variable assignment in the original statement declaration. So you statement would be something like:
SELECT COUNT(*) FROM train WHERE ?<=0 INTO _a
Then you you would execute it with:
EXECUTE stmt1 using _car;
And get the result with:
select _a;
Let me know if it works.