I'm learning Functions, Procedures and Triggers and I wanted to do a easy procedure that count the rows in a table from parameters.
create procedure countRows(IN v varchar(30))
SELECT COUNT(*) FROM v;
Can someone tell me why if I do:
call countRows('sometable');
call countRows(sometable); //I tried both
It just don't work
Sorry for that newbie question.
You need dynamic sql.
Solution for returning count of any table passed as a parameter to sp
DELIMITER $$
CREATE PROCEDURE `countRows`(IN v varchar(30))
BEGIN
SET #t1 =CONCAT("SELECT COUNT(*) FROM ",V);
PREPARE stmt3 FROM #t1;
EXECUTE stmt3;
DEALLOCATE PREPARE stmt3;
END$$
DELIMITER ;
Execution
call countRows('sometable');
Update: Solution for returning "Table x contain n row(s)" for a table passed as a parameter to sp
DELIMITER $$
CREATE PROCEDURE `countRowsEx`(IN v VARCHAR(30))
BEGIN
-- SET #t1 =CONCAT("SELECT COUNT(*) FROM ",V);
SET #t1 =CONCAT('SET #totalRows=(SELECT COUNT(*) FROM ',v, ' );');
PREPARE stmt3 FROM #t1;
EXECUTE stmt3;
DEALLOCATE PREPARE stmt3;
SELECT CONCAT( 'Table ', v, ' contains ', #totalRows, ' row', IF(#totalRows>1, 's',''));
END$$
DELIMITER ;
Execution
call countRowsEx('sometable');
You can use information_schema for this.
for example to find rows count for table with name stored in variable v use this:
select table_rows from information_schema.tables where table_name = v;
Try this:
call countRows('v');
Related
I hope someone can help me. I want to get back all the rows which are updated and i found something in this forum. But now i created a 'PROCEDURE' and wanted to combine the Update statement with the needed other statements as Strings and execute the String with the 'PREPARE' statement. But because of some reasons this doesn't work. The Query (not as String) itself works.
Can someone help me ?
DELIMITER $$
DROP PROCEDURE IF EXISTS updateAndGetUpdatedRows$$
CREATE PROCEDURE updateAndGetUpdatedRows (IN query varchar(255))
BEGIN
SET #buffer = CONCAT_WS(' ','SET #uids := null;',query,'AND ( SELECT #uids := CONCAT_WS(",", ID, #uids) );','SELECT #uids;');
PREPARE stmt FROM #buffer;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
call updateAndGetUpdatedRows('UPDATE expensesData SET value = 22 WHERE ID = 64');
System:
innodb_version: 5.5.55-MariaDB-38.8
protocol_version: 10
slave_type_conversions
version: 5.5.57-MariaDB
version_comment: MariaDB Server
version_compile_machine: x86_64
version_compile_os: Linux
Because of P.Salmon i figured it out. Following the solution:
DELIMITER $$
DROP PROCEDURE IF EXISTS updateAndGetUpdatedRows$$
CREATE PROCEDURE updateAndGetUpdatedRows (IN query varchar(255))
BEGIN
SET #uids := null;
SET #buffer = CONCAT_WS(' ',query,'AND ( SELECT #uids := CONCAT_WS(",", ID, #uids) );');
PREPARE stmt FROM #buffer;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SELECT #uids;
END$$
DELIMITER ;
i am creating a dynamic query in stored procedure. my stored procedure is as follows:
CREATE PROCEDURE `test1`(IN tab_name VARCHAR(40),IN w_team VARCHAR(40))
BEGIN
SET #t1 =CONCAT("SELECT * FROM ",tab_name," where team=",w_team);
PREPARE stmt3 FROM #t1;
EXECUTE stmt3;
DEALLOCATE PREPARE stmt3;
END
when i try to run it with the following call:
call test1 ('Test','SPA');
i get the following error message:
Error Code: 1054. Unknown column 'SPA' in 'where clause'
i tested without where condition and it works fine, but with the where condition its not working, i tried using # with the variable name but it still does not work.
Thanks for your help.
Error Code: 1054. Unknown column 'SPA' in 'where clause'
This happens when you do not enclose input string within quotes, and SQL engine tries to identify it as a column in the table being queried. But it fails as it can't find it.
But what happens when it finds such column?
It fetches results when it finds some matches on the column values.
Obviously this is not what one was expecting.
How to overcome this? Use Prepared Statements with dynamic input values.
You can use placeholders like ? in stored procedures too on dynamic input values to use with Prepared Statements. The engine will handle escape characters and other string values when assigned to or compared within SQL expressions.
You just need to re-assign procedure inputs to one or more session variables, as required.
Example on your procedure:
CREATE PROCEDURE `test1`( IN tab_name VARCHAR(40), IN w_team VARCHAR(40) )
BEGIN
SET #t1 = CONCAT( 'SELECT * FROM ', tab_name, ' where team = ?' ); -- <-- placeholder
SET #w_team := w_team;
PREPARE stmt3 FROM #t1;
EXECUTE stmt3 USING #w_team; -- <-- input for placeholder
DEALLOCATE PREPARE stmt3;
END;
You missed to enclose the parameter w_team in WHERE clause.
Try like this:
SET #t1 =CONCAT("SELECT * FROM ",tab_name," where team='",w_team,"'");
Explanation:
Query from your code would be like:
SELECT * FROM Test where team=SPA
It will try find a column SPA which is not available, hence the error.
And we changed it to:
SELECT * FROM Test where team='SPA'
Try this..
CREATE PROCEDURE `test1`(IN tab_name VARCHAR(40),IN w_team VARCHAR(40))
BEGIN
SET #t1 =CONCAT("SELECT * FROM ",tab_name," where team='",w_team,"'");
PREPARE stmt3 FROM #t1;
EXECUTE stmt3;
DEALLOCATE PREPARE stmt3;
END
You are missing quotes around w_team variable..
you should print the statement that dynamically build so you can just copy printed statement and try so you can easily find this kind of problem.
select #t1 will print the statment that build dynamically..
you can add dynamic fields and condition by using CONCAT() MySQL function. I checked this is working fine.
DELIMITER $$
/*define procedure name*/
CREATE PROCEDURE getSearchData()
BEGIN
DECLARE conditions varchar(1000);
DECLARE selectField varchar(1000);
DECLARE SQL_QUERY varchar(1000);
/*define default select and condition*/
SET #selectField = 'status,id';
set #conditions = ' where return_flight=0';
SET #SQL_QUERY = CONCAT('SELECT ',#selectField, ' FROM flights ',#conditions);
/* you can add more select fields and conditions according to your requirement */
PREPARE stmt1 FROM #SQL_QUERY ;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END$$
DELIMITER ;
Here is my code
Drop procedure if exists test//
CREATE PROCEDURE test(IN woeid VARCHAR(15))
BEGIN
SET #w1 := woeid;
SET #sql = CONCAT('CREATE OR REPLACE VIEW temp
AS
SELECT *
FROM test_table gp
WHERE gp.name =', #w1);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END//
Delimiter ;
call test('ABCD');
I am getting error as
Error code: 1054. Unknown column 'ABCD' in 'where' clause
Please help.
It sounds as though you're needlessly using views, when some other approach would be more appropriate.
However, the reason it isn't working is that you haven't quoted your string literal, so the resulting SQL contains WHERE gp.name = ABCD whereas it at very least needs to be WHERE gp.name = 'ABCD'. You can use MySQL's QUOTE() function for this purpose, but it's better to parameterise the value:
DELIMITER //
DROP PROCEDURE IF EXISTS test//
CREATE PROCEDURE test(IN woeid VARCHAR(15))
BEGIN
SET #w1:=woeid, #sql:=CONCAT('
CREATE OR REPLACE VIEW temp AS
SELECT *
FROM test_table
WHERE name = ?
');
PREPARE stmt FROM #sql;
EXECUTE stmt USING #w1;
DEALLOCATE PREPARE stmt;
SET #w1:=NULL, #sql:=NULL;
END//
DELIMITER ;
CALL test('ABCD');
I have the following stored procedure:
DELIMITER ///
CREATE PROCEDURE tmp_test_proc(__TABLE__NAME varchar(255))
BEGIN
SELECT COUNT(*) FROM __TABLE__NAME;
END///
DELIMITER ;
I would like to select from the parameter __TABLE__NAME, but MySQL tells me there is no table __TABLE__NAME... So is there a way to use the value of the parameter in the from clause?
you cannot parameterized table names (as well as column names) by default, you need to create PreparedStatement for this,
DELIMITER ///
CREATE PROCEDURE tmp_test_proc(__TABLE__NAME varchar(255))
BEGIN
SET #sql = CONCAT('SELECT COUNT(*) FROM ', __TABLE__NAME);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END///
DELIMITER ;
I write a store procedure.But it don't take the table name as a parameter.Now how i send a table name as aparameter.Pls see my proc below:
DELIMITER $$
USE `db_test`$$
DROP PROCEDURE IF EXISTS `test_proc`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `test_proc`(IN newsInfoTable VARCHAR(100))
BEGIN
SELECT news INTO #news
FROM newsInfoTable
WHERE CURDATE()=DATE_FORMAT(date_time,'%Y-%m-%d')
ORDER BY date_time DESC LIMIT 1;
SELECT #news;
END$$
DELIMITER ;
Calling parameter:
USE db_test;
CALL test_proc('tbl_news_list');
But the ERROR is: Table 'db_test.newsinfotable' doesn't exist
How solve this problem.Pls help.
Use prepared statements in your procedure body:
SET #s = CONCAT('SELECT ... FROM ', newsInfoTable);
PREPARE stmt FROM #s;
EXECUTE stmt;
//.....
DEALLOCATE PREPARE stmt;
Your code should look like :
SET #sql_stam = CONCAT('SELECT news INTO #news FROM ',newsInfoTable,
' WHERE DATE_FORMAT(date_time,\'%Y-%m-%d\')
ORDER BY date_time DESC LIMIT 1');
...
SELECT #news;
Also, I don't see any reasons you need to use #news variable...