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 ;
Related
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;
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 have 2 schemas with exactly the same tables schema_oltp and schema_olap. I want to delete from selected tables in schema_oltp only the data which already exists in schema_olap. The tables I want to delete from are listed in a table called archived_to_delete. For each of the tables listed in archived_to_delete, I need to delete the data in batches of 100 000. This is what I have so far. It only deletes 100 000 in each table and stops. I want it to continue until there is no data in schema_oltp which also exists in schema_olap:
DELIMITER $$
CREATE DEFINER=`root`#`%` PROCEDURE `schema_oltp`.`schemaDeletes`(IN from_schema VARCHAR(100), IN to_schema VARCHAR(100))
BEGIN
DECLARE v_tname varchar(100);
DECLARE v_pkey varchar(455);
DECLARE v_upfield varchar(455);
DECLARE done INT DEFAULT 0;
DECLARE v_limit INT DEFAULT 100000;
DECLARE v_deleted INT;
DECLARE table_cursor CURSOR FOR SELECT a.table_name, a.column_name
FROM INFORMATION_SCHEMA.COLUMNS a
INNER JOIN archived_to_delete b
ON a.table_name = b.table_name
WHERE TABLE_SCHEMA = 'schema_oltp'
AND COLUMN_KEY='PRI'
ORDER BY b.archived_to_delete_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN table_cursor;
REPEAT
FETCH table_cursor INTO v_tname, v_pkey;
IF NOT done THEN
SET v_deleted=0;
SET #sql = CONCAT('DELETE FROM ',from_schema,'.', v_tname, ' WHERE ',v_pkey,' IN (SELECT ', v_pkey, ' FROM ',to_schema,'.', v_tname, ') limit ',v_limit,';');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET v_deleted=v_deleted+1;
IF v_deleted = v_limit THEN
commit;
SET v_deleted=0;
END IF;
SELECT CONCAT('Deleting...',v_tname);
END IF;
UNTIL done END REPEAT;
CLOSE table_cursor;
END$$
DELIMITER ;
I need to update special column in every table that which name start with :-
`REPORT_<"DATE PATERN">`
How actually I can do it?.
upd:
I've tried to write stored procedure, but I'm not familiar with it, so it does not work:
DELIMITER $$
DROP PROCEDURE IF EXISTS `debug_msg`$$
CREATE PROCEDURE debug_msg(enabled INTEGER, msg VARCHAR(255))
BEGIN
IF enabled THEN BEGIN
select concat("** ", msg) AS '** DEBUG:';
END; END IF;
END $$
DELIMITER $$
DROP PROCEDURE IF EXISTS changeColumnType;
CREATE PROCEDURE changeColumnType ()
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE tableName varchar(100);
DEClARE table_cursor CURSOR FOR
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME LIKE '%REPORT_%';
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN table_cursor;
get_tableName: LOOP
FETCH table_cursor INTO tableName;
IF v_finished = 1 THEN
LEAVE get_tableName;
END IF;
call debug_msg(1, tableName);
ALTER TABLE tableName MODIFY COLUMN TIME VARCHAR(8);
END LOOP get_tableName;
CLOSE table_cursor;
END$$
DELIMITER ;
I have the following error:
ERROR 1146 (42S02): Table 'test.tablename' doesn't exist.
I fails on this step ALTER TABLE tableName MODIFY COLUMN TIME VARCHAR(8);
Resolved it by adding prepared statement
SET #table = tableName;
SET #s1 = CONCAT('ALTER TABLE ', #table, ' MODIFY COLUMN TIME VARCHAR(8);');
PREPARE stmt FROM #s1;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
procedure in mysql
can some one please help me
iam new to mysql
creating a stored procedure to delete rows from a date column older than 30 days from all tables in my database in mysql
You can do something like this:
DELETE FROM MyTable
WHERE MyTable.MyDate < SUBDATE(#NOW, 30)
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 ;