I am trying to make a function witch create a new ID from any table given as parameter.
DROP FUNCTION IF EXISTS create_id;
DELIMITER $$
CREATE FUNCTION create_id(db_table TEXT,pkey TEXT,strlen INT,joinner TEXT)
RETURNS TEXT
BEGIN
DECLARE max_id TEXT;
DECLARE new_id TEXT;
SET max_id = (SELECT MAX(pkey) FROM db_table);
SET new_id = max_id;
RETURN new_id;
END;
$$
DELIMITER ;
Thank you for your answers
You can't use variables like you want to; basically, if you want a variable identifier (table name, column name or the-like), you need to use dynamic SQL. But MySQL functions do not support dynamic SQL. So, instead, you need to use a procedure with an OUT paramter.
Consider:
drop procedure if exists create_id;
delimiter $$
create procedure create_id(in _db_table text, in _pkey text, out _max_id int)
begin
set #max_id = null;
set #sql = concat('select max(`', _pkey, '`) into #max_id from `', _db_table, '`');
prepare stmt from #sql;
execute stmt;
deallocate prepare stmt;
set _max_id = #max_id;
end;
$$
delimiter ;
Then, you invoke the procedure and recover the out value like so:
call create_id('mytable', 'id', #max_id);
select #max_id;
Note: I couldn't see the point for the last two arguments to your original function, so I removed them.
Related
I have to send comma separated values into a select statement where it will update values through #sql statement.
I have common table in all Databases I need to update the table column by one update statement in the procedure.
For Example : Input Param will be ('DataBase1','Database2',....., 'Database10')
Below is the sample procedure :
DELIMITER &&
CREATE PROCEDURE update_stmt (IN DBName varchar(100))
BEGIN
Declare DBName = #DB;
**comma seperated values loop and placed into the #DB**
use #DB;
SELECT concat(update #DB.sample SET COL = 0 where ID = \'',ID,'\','; ) as stmt FROM
Test.Sample into #s;
SET #sql = #s
PREPARE stmt from #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END &&
DELIMITER ;
so that update statement will execute in each of the databases.
Here's another approach. I don't try to split the comma-separated string, I use it with FIND_IN_SET() to match schema names in INFORMATION_SCHEMA.TABLES. This filters to schemas in the list that actually exist, and tables that actually exist in that schema.
Then use a cursor to loop over the matching rows, so you don't have to split any strings, which is awkward to do in a stored procedure.
I supposed that you would want to specify the id of the row to update too, so I added that to the procedure parameters.
Also notice the use of quotes when I create #sql. You can concatenate strings, but those must be quote-delimited like any other string literal. Variables must not be inside the quoted string. There's no feature to expand variables inside string literals in MySQL.
DELIMITER &&
CREATE PROCEDURE update_stmt (IN schema_name_list VARCHAR(100), IN in_id INT)
BEGIN
DECLARE done INT DEFAULT false;
DECLARE schema_name VARCHAR(64);
DECLARE cur1 CURSOR FOR
SELECT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'sample' AND FIND_IN_SET(TABLE_SCHEMA, schema_name_list);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;
SET #id = in_id;
OPEN cur1;
schema_loop: LOOP
FETCH cur1 INTO schema_name;
IF done THEN
LEAVE schema_loop;
END IF;
SET #sql = CONCAT('UPDATE `', schema_name, '`.sample SET col = 0 WHERE id = ?');
PREPARE stmt FROM #sql;
EXECUTE stmt USING #id;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur1;
END &&
DELIMITER ;
Frankly, I hardly ever use stored procedures in MySQL. The procedure language is primitive, and the tasks I see people try to do in stored procedures could be done a lot more easily in virtually every other programming language.
I want to create multiple tables with just one statement (query).
Loop
start
(
create table a
)
a =a +1
end loop
So say it has to create 100 tables labeled as TABLE1, TABLE2, ...
Try the following procedure.
DROP PROCEDURE IF EXISTS `createTableProcTest`;
delimiter //
CREATE PROCEDURE `createTableProcTest`()
BEGIN
DECLARE count INT Default 0;
simple_loop: LOOP
SET #a := count + 1;
SET #statement = CONCAT('Create table Table',#a,' ( name VARCHAR(70), age int );');
PREPARE stmt FROM #statement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET count = count + 1;
IF count=100 THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END//
In order to execute just do the following:
Call createTableProcTest();
By executing the above procedure 100 tables will be created having name table1,...,table100.
And the table structure would look like following:
N:B: Procedure execution might take several seconds. Don't be impatient.
You need give us more details but, I think is easier to call a stored procedure, inside the loop, to create the procedure.
You need to create a procedure to create the tables you need and call this procedure inside the loop.
Ex:
CREATE PROCEDURE SP_Create_Table(IN tableName VARCHAR(50)) BEGIN SET
#sql = CONCAT('CREATE TABLE ', tableName, '(column1 INT(11))');
PREPARE stmt FROM #sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END
Now, call the create table procedure inside the loop
DELIMITER // CREATE FUNCTION CalcIncome ( starting_value INT ) RETURNS
INT BEGIN
DECLARE income INT; SET income = 0; label1: WHILE income <=
50 DO
call SP_Create_Table(CONVERT(VARCHAR(50),starting_value)); END WHILE label1; RETURN income; END; // DELIMITER;
Can anybody help me with this JSP problem.
Im trying to update the database using code similar to this:
So, I have this on my Servlet:
String QueryCondition = "id = 1";
That will be passed to this stored procedure:
CREATE
DEFINER=`root`#`localhost`
PROCEDURE `storedprocedure_1`(QueryCondition TEXT)
BEGIN
UPDATE users SET name = 'John'
WHERE QueryCondition;
END
I was thinking if this is possible because the update always fail.
If this isn't possible can you recommend how can i do such thing
You can use it in a stored procedure but with a prepared statement.
Example:
DELIMITER //
CREATE
DEFINER=root#localhost
PROCEDURE storedprocedure_1(QueryCondition TEXT)
BEGIN
SET #query := CONCAT( 'UPDATE users SET name = \'John\' WHERE ',
QueryCondition );
PREPARE stmt FROM #query;
EXECUTE stmt;
DROP PREPARE stmt;
END;
//
DELIMITER ;
I have several MySQL tables that maintains a tree structure of records. Each record have an ID and a Parent field. I want to write a stored function to get the parent ID, given a record ID.
The following is my first attempt, and it's incorrect. My problem is I do not know how to use variable table name.
delimiter $$
create function parent(
tableName varchar(15),
nodeId int
) returns int
begin
declare p int;
select parent into p from tableName where id=nodeId;
return p;
end$$
Please help. Thanks!
After some research, apparently a stored function will not work in this case due to the fact stored functions cannot execute dynamic SQL. I change my implementation to a stored procedure.
delimiter $$
create procedure parent(tableName varchar(15), nodeId int)
begin
set #s := concat('select parent from ', tableName, ' where id =', nodeId);
prepare query from #s;
execute query;
deallocate prepare query;
end$$
delimiter ;
Hello dearest community,
EDITED
This is my solution, based on Devart answer. I slightly modify the procedure parameter and also fix some % things..
DELIMITER $$
DROP PROCEDURE IF EXISTS `cosmedicdb`.`proc_searchall` $$
CREATE PROCEDURE `cosmedicdb`.`proc_searchall` (output TEXT, tbl varchar(50), kolom_kriteria VARCHAR(20),
kolom_nilai VARCHAR(20))
BEGIN
SET #query = CONCAT('SELECT ', output, ' FROM ',tbl,' WHERE ', kolom_kriteria, ' LIKE CONCAT(','\'%',kolom_nilai, '%\')');
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
I think one can enhance this to support search of numeric value field
Original Question below
First of all, I hope this is not a repost question.
I want to create a flexible search procedure. That is, the column ad the value of the column to be search, can be supplied from the argument itself. Currently this is my search procedure looks like :
DELIMITER $$
DROP PROCEDURE IF EXISTS `cosmedicdb`.`proc_searchtindakan` $$
CREATE PROCEDURE `cosmedicdb`.`proc_searchtindakan` (kolom VARCHAR(20),
kolomnilai VARCHAR(20))
BEGIN
CASE kolom
WHEN 'jenis'
THEN
SELECT jenis, harga
FROM cosmedicdb.tb_mastertindakan
where jenis like concat('%',kolomnilai,'%');
END CASE;
END $$
DELIMITER ;
You can see that this procedure only work for certain column to be search. Is it possible (and safe) to create just one search procedure that allows me to search using any column as the defining search criteria?
Thanks
You can do it with a prepared statements: build a query and execute it, e.g. -
DELIMITER $$
CREATE PROCEDURE proc_searchtindakan(IN kolom VARCHAR(20), IN kolomnilai VARCHAR(20))
BEGIN
SET #query = CONCAT('SELECT ', kolom, 'FROM cosmedicdb.tb_mastertindakan WHERE ', kolom, ' LIKE CONCAT(\'%\'', kolomnilai, '\'%\'');
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;
...in example I have removed 'harga' field from the list of fields; add it if you need.