Have anyone faced the same problem as mine ? please kindly help !!
I have two procedures and one event, the procedures are working just fine when I call them separately from the command line.
But those procedures can not be called from inside the mysql event.
Below are my procedures, mysql event and how I check the effective result:
USE ims_db;
DELIMITER;
DROP PROCEDURE IF EXISTS CreatePartition$$
CREATE PROCEDURE CreatePartition(day_keep_data INT)
BEGIN
DECLARE partition_temp TEXT;
DECLARE partition_name CHAR(12);
DECLARE partition_threshold INT DEFAULT 0;
DECLARE day_temp INT;
SET day_temp = day_keep_data;
SET #sql = concat('ALTER TABLE ims_db.ims_counter PARTITION BY RANGE(trigger_time)(');
loop_change_partition: LOOP
IF day_temp <= 0 THEN
LEAVE loop_change_partition;
END IF;
SET day_temp = day_temp - 1;
SET partition_threshold = UNIX_TIMESTAMP() - 86400*day_temp;
SET partition_name = concat('p', CURRENT_DATE() - INTERVAL day_temp DAY + 0);
SET partition_temp = concat('PARTITION', partition_name, ' VALUES LESS THAN (', partition_threshold,'), ');
SET #sql = concat(#sql, partition_temp);
END LOOP loop_change_partition;
SET partition_name = concat('p', CURRENT_DATE() + INTERVAL 1 DAY + 0);
SET partition_temp = concat('PARTITION', partition_name, ' VALUES LESS THAN MAXVALUE);');
SET #sql = concat(#sql, partition_temp);
prepare stmt from #sql;
execute stmt;
deallocate prepare stmt;
END$$
DELIMITER ;
DELIMITER $$
DROP PROCEDURE IF EXISTS DeleteOldData$$
CREATE PROCEDURE DeleteOldData(day_keep_data INT)
BEGIN
SET #sql = concat('DELETE FROM ims_db.ims_counter WHERE ims_db.ims_counter.id > 0
AND ims_db.ims_counter.trigger_time < ', UNIX_TIMESTAMP() - 86400*day_keep_data);
prepare stmt from #sql;
execute stmt;
deallocate prepare stmt;
ALTER TABLE ims_counter REMOVE PARTITIONING;
END$$
DELIMITER ;
-- DELIMITER $$
-- CREATE FUNCTION ims_daily_work() RETURNS INT(11)
-- BEGIN
-- CALL DeleteOldData(30);
-- CALL CreatePartition(30);
-- END $$
-- DELIMITER ;
DELIMITER $$
CREATE EVENT IMSDailyWork
ON SCHEDULE EVERY 30 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 10 SECOND
DO
BEGIN
CALL DeleteOldData(30);
CALL CreatePartition(30);
-- SELECT ims_daily_work();
END$$
DELIMITER ;
How I check the effective result:
run command: show table status like 'ims_counter'\G -> check Create_options: -> it is null
after running all the above event and procedures -> check again Create_options: -> it should be 'partitioned', but my problem is there's no such 'partitioned' like that.
I found the solution: it is because my 'event_scheduler' is OFF, so no EVENT can be launched.
to check event status: show global variables like 'event_scheduler';
to enable event_scheduler: set global event_scheduler=1;
Related
I am trying to create a Procedure during the creation of a database, the mysql query is as follows:
CREATE DATABASE database_Sensor1;
USE database_Sensor1;
CREATE TABLE Persons(id int NOT NULL);
DELIMITER //
CREATE PROCEDURE MYLOOP() IF database_Sensor1 EXISTS
BEGIN
DECLARE i int;
DECLARE str varchar(255);
SET i = 0;
WHILE i < 32 DO
SET str = CONCAT('col_',i);
SET #sql = CONCAT('ALTER TABLE persons ADD ',str,' float;');
SET i = i + 1;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END WHILE;
END
DELIMITER ;
CALL MYLOOP();
But I get this error:
#1305 - PROCEDURE database_sensor1.MYLOOP does not exist
I am trying to use the Procedure to Loop the table creation by quickly altering the table to add 32 columns in so that I can run another .php to add in the values.
CREATE DATABASE database_Sensor1;
USE database_Sensor1;
CREATE TABLE database_Sensor1.Persons(id int NOT NULL);
DELIMITER //
CREATE PROCEDURE database_Sensor1.MYLOOP()
BEGIN
DECLARE i int;
DECLARE str varchar(255);
SET i = 0;
WHILE i < 32 DO
SET str = CONCAT('col_',i);
SET #sql = CONCAT('ALTER TABLE database_Sensor1.persons ADD ',str,' float;');
SET i = i + 1;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END WHILE;
END
//
DELIMITER ;
CALL MYLOOP();
Editions:
IF database_name EXISTS construction not exists. Removed. See edition 3.
Procedure creation code is not finalized with delimiter. Added.
The database in which the procedure must be created is not specified explicitly. Added. If the database not exists then the error will be generated. The same with the table name.
I'm trying to write a stored procedure in MySQL that will receive two dates. A from date and a two date. I've written stored procedures before but I'm stumped as to where to start with this.
How can I code a stored procedure that, when it received 20170101 and 20170110 it adds the following to a table
20170101
20170102
20170103
20170104
20170105
20170106
20170107
20170108
20170109
20170110
I don't simply want to add one to each value as they are dates and 20170132 doesn't exist in reality.
Thank you everyone
This might help you.
CREATE TABLE IF NOT EXISTS table_name (field_name VARCHAR(255));
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `test1`$$
CREATE PROCEDURE `test1`(
IN pi_date_from DATE,
IN pi_date_to DATE
)
READS SQL DATA
BEGIN
SET #countRecordToAdd = 0;
SET #i = 0;
SET #query = 'INSERT INTO table_name (field_name) VALUES ';
SELECT
DATEDIFF(pi_date_to, pi_date_from)
INTO
#countRecordToAdd
;
IF #countRecordToAdd > 0
THEN
label1: LOOP
SET #query = CONCAT(
#query,
" (date_add(\"", pi_date_from, "\", INTERVAL ", #i, " DAY)),"
);
SET #i = #i + 1;
IF #i <= #countRecordToAdd THEN ITERATE label1;END IF;
LEAVE label1;
END LOOP label1;
PREPARE stmt FROM TRIM(TRAILING ',' FROM #query);
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END$$
DELIMITER ;
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;
I have a procedure call that updates a set of data and then returns the data set for my to render. Everything works fine except that, I cant do both operations at once. If I do the update, then the procedure, won´t return any value and vice versa. I have seen some answers suggesting to use temptables but I could not find how to retrieve the dataset. I appreciate any help even if it comes to improving my query.
CREATE DEFINER=`root`#`localhost` PROCEDURE `prueba`(IN `idUsuario` INT)
MODIFIES SQL DATA
BEGIN
DECLARE flag INT DEFAULT FALSE;
DECLARE done INT DEFAULT FALSE;
DECLARE idNotificacion INT DEFAULT 0;
DECLARE cont INT DEFAULT 0;
DECLARE resultset CURSOR FOR SELECT id FROM notificaciones WHERE involvedA_idUsuario=idUsuario AND active=1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN resultset;
SET #query = "SELECT * FROM notificaciones n WHERE n.id IN('null'";
the_loop: LOOP
FETCH resultset INTO idNotificacion;
IF done THEN
LEAVE the_loop;
END IF;
SET cont = cont + 1;
SET flag = TRUE;
SET #query = CONCAT(#query," , " ,idNotificacion);
UPDATE notificaciones SET active=0 WHERE id=idNotificacion;
END LOOP the_loop;
CLOSE resultset;
IF flag THEN
SET #query = CONCAT(#query, ")");
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END
Do you really need a cursor? An option like this, maybe it can be useful:
/* Procedure structure for procedure `prueba` */
/*!50003 DROP PROCEDURE IF EXISTS `prueba` */;
DELIMITER $$
CREATE PROCEDURE `prueba`(`idusuario` INT)
BEGIN
DECLARE `ids` LONGTEXT DEFAULT NULL;
SELECT GROUP_CONCAT(`id`) INTO `ids`
FROM `notificaciones`
WHERE `involveda_idusuario` = `idusuario` AND `active` = 1;
IF (`ids` IS NOT NULL) THEN
SET #`stmt` := CONCAT('UPDATE `notificaciones`
SET `active` = 0
WHERE `id` IN (', `ids`, ')');
PREPARE `exec` FROM #`stmt`;
EXECUTE `exec`;
SET #`stmt` := CONCAT('SELECT `id`, `involveda_idusuario`, `active`
FROM `notificaciones` `n`
WHERE `n`.`id` IS NULL OR `n`.`id` IN (', `ids`, ')');
PREPARE `exec` FROM #`stmt`;
EXECUTE `exec`;
DEALLOCATE PREPARE `exec`;
END IF;
END$$
DELIMITER ;
You must be careful with GROUP_CONCAT and the system variable group_concat_max_len.
SQL Fiddle demo
can any one please help me to write a procedure for
mysql function or procedure
where the input will be a schema name
you need to read all the list of tables in the scheme using meta data
and for each table where you have a column "PRS_DATE",
delete the rows that are 30 days old
based on this "PRS_DATE" column value.
delimiter //
create procedure delete_data(schemata varchar(25))
Begin
DECLARE tab_name varchar(64);
DECLARE done TINYINT DEFAULT 0;
DECLARE table_name_cur cursor for select table_name from information_schema.TABLES where table_schema=schemata;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN table_name_cur;
read_loop: LOOP
FETCH table_name_cur INTO tab_name;
IF done THEN LEAVE read_loop; END IF;
-- delete from tab_name where PRS_DATE < now() - interval 1 month;
set #x =concat('delete from ', tab_name,' where ','PRS_DATE \< ', 'now() - interval 1 month');
select #x;
prepare stmt2 from #x;
execute stmt2;
deallocate prepare stmt2;
END LOOP;
CLOSE table_name_cur;
END //
delimiter ;