I have a requirement to write a SP where -
1. Select the rows count which match the given where clause.
2. Loop on the row counts and execute the delete query with limit n, till the time row count is not 0.
3. Decrease the row count value by n.
SP written -
BEGIN
DECLARE current_timestamp_millis BIGINT;
DECLARE RETENTION_DAYS SMALLINT;
DECLARE numRows BIGINT DEFAULT 0;
-- No. of days to retain data for
SET RETENTION_DAYS = 1;
-- Current epoch timestamp in millis
SET current_timestamp_millis = UNIX_TIMESTAMP(NOW())*1000;
-- SQL query to get the count of rows ,eligible to get deleted.
select count(*) as numRows from table1 where state = 2 AND end_time < (UNIX_TIMESTAMP(NOW())*1000 - (1 * 24 * 60 * 60 * 1000)) ;
-- Loop on the num of rows from above select query and delete the rows in chunks of 100
WHILE(numRows >=0)
DO
Insert into test_t values(current_time_millis);
Delete from table1 where end_time < ((UNIX_TIMESTAMP(NOW())*1000 - (1 * 24 * 60 * 60 * 1000))) limit 100;
SET numRows = numRows - 100;
DO SLEEP(2);
END WHILE;
END;
You are not setting up numrows try select..into numrows.
Related
Hi Can any one please help me with a procedure for inserting 7 million records for 7 years (million records each year) in loop in MYSQL,
I need to insert in a batch of 500,000 for each batch .
Data is there in table "Archive_data", need to insert in "Stg_table"
Archive data has yearly sales, i want to write a loop in MYSQL looping on Year and insert in a batch of 500K each
i tried
insert into SDL_Stg_Bill_Details
select SDL_Id, Rec_Is_Processed, concat(Bill_Header_Key,'_',Row_Num), Bill_Header_Key,Row_Num from (
SELECT SDL_Id, Rec_Is_Processed, Bill_Details_Key, Bill_Header_Key,
ROW_NUMBER() OVER(partition by Bill_Header_Key order by SDL_Id ) Row_Num
FROM PANTALOONS_SOLUS_PROD.SDL_Stg_Bill_Details_Archive
where EXTRACT(YEAR_MONTH FROM Bill_Date) in ('201406',
'201407',
'201408',
'201409',
'201410') ff
i am getting lock wait time out exceeded error if i am trying 7 M records
at once
Thanks in advance
Not sure if this is what you want, but I hope with some tweaks it might help you:
DELIMITER $
CREATE PROCEDURE CopyDataInBatch()
BEGIN
DECLARE x INT;
DECLARE y INT;
SET x = 1;
SET y = x + 10000;
the_loop : LOOP
IF x > 1000000 THEN /* Use the number of rows you wanted to copy*/
LEAVE the_loop;
END IF;
INSERT INTO table_in_which_copying (col_name_1, col_name_2)
SELECT (col_name_1, col_name_2) FROM table_from_which_copying
ORDER BY (col_name_1)
LIMIT x, y;
SET x = x + 10000;
SET y = y + 10000;
SELECT "Copied 10000 rows"; /* Only for testing... better remove it(?)*/
END LOOP;
END $
DELIMITER ;
I have a query :
insert into fookoo_business
select stat_date, sum(spend), sum(revenue)
from hooloo_business;
that i want to run for each date from '2017-01-20' until yesterday (it means the query will run 434 times if we're at 01/04/2018), for each date separately
(in a loop).
how can i create a loop in Mysql to do it for me?
I have tried:
creating procedure for the query select #stat_date, sum(spend), sum(revenue)
I called 'query'
then :
CREATE PROCEDURE loop_procedure()
BEGIN
SET #stat_date='2018-03-20';
CALL 'query';
REPEAT
SET #stat_date = #stat_date + INTERVAL 1 DAY;
UNTIL #stat_date = CURDATE() END REPEAT;
END
eventually i've used the following logic within a stored procedure to fetch the data:
PROCEDURE `x_monitoring_loop`()
BEGIN
DECLARE i INT;
DECLARE len INT;
SET len = 434;
SET i = 0;
WHILE (i < len) DO
SET #stat_date= CURDATE()-INTERVAL 1 DAY;
SET #stat_date= #stat_date- INTERVAL i DAY;
Insert query;
SET i = i +1;
END WHILE;
This way the query ran 434 times for each day, beginning at current date - 1 day.
I do not know why you want to use a procedure,I think we can just use a query sql to do it:
INSERT INTO fookoo_business
SELECT stat_date, SUM(spend), SUM(revenue)
FROM hooloo_business
WHERE stat_date BETWEEN STR_TO_DATE('2017-01-02', '%Y-%m-%d') -- start date
AND DATE_SUB(NOW(), INTERVAL 1 DAY) -- end date
GROUP BY stat_date;
I have 100 rows in table tbl_master_sales and an empty table tbl_customer_sales.When I use WHILE loop to insert data from tbl_master_salesto tbl_customer_sales,it only inserts 50 rows.However,it should have insert 100 rows taking two iteration of while loop.What may be my mistake in following PROCEDURE:
CREATE PROCEDURE ROWPERROW()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM tbl_master_sales INTO n;
SET i=0;
WHILE i<n DO
INSERT INTO tbl_customer_sales (id,card_number,customer_name,customer_phone,bill_no,item_code,division,section,department,item_name,store,promo_name,billdiscount_name,billqty,promo_amount,bill_discount_amount,loyaltyamount,net_amount)
SELECT id, card_number, customer_name, customer_mobile, billno, itemcode, division, section, department, itemname, store, promoname, billdiscountname, billqty, promoamount, billdiscountamount, loyaltyamount, netamount
FROM tbl_master_sales
WHERE NOT EXISTS(SELECT 1
FROM tbl_customer_sales
WHERE id=tbl_master_sales.id)
LIMIT i,50;
SET i = i + 50;
END WHILE;
End;;
I don't see anything wrong with your procedure code logic but the reason for inserting only 50 rows could be the NOT EXISTS part shown below, which is restricting from inserting duplicate rows (or) filtering out the rest records.
WHERE NOT EXISTS(
SELECT 1
FROM tbl_customer_sales
WHERE id=tbl_master_sales.id)
I have a 200k rows mysql table, and a column with empty value, and i like to populate this column with random numbers from 1 to 10,000.
I don't know if its possible to have a query something like this:
UPDATE 'videos'
SET 'views' = rand(1,10000)
RAND() produces random float values from 0 to 1. Could you try this?
Update videos set views = CAST(RAND() * 10000 AS UNSIGNED)
Try this one. It can generate a random number between 1 to 10000.
UPDATE videos
SET views = FLOOR(rand() * 10000) + 1;
Or this:
UPDATE videos SET views = FLOOR(1 + rand() * 10000 );
updating Table records with random phone numbers
DECLARE #OrderDetailID INT
DECLARE #Phone VARCHAR(100)
DECLARE MY_CURSOR CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT DISTINCT
OrderDetailID
FROM dbo.OrderDetailTBL
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO #OrderDetailID
WHILE ##FETCH_STATUS = 0
BEGIN
--Do something with Id here
SET #Phone = '(' + CONVERT(VARCHAR(3), CONVERT(NUMERIC(3, 0), RAND()
* 899)) + ') ' + CONVERT(VARCHAR(3), CONVERT(NUMERIC(3, 0), RAND()
* 899)) + '-' + CONVERT(VARCHAR(4), CONVERT(NUMERIC(4, 0), RAND()
* 8999))
UPDATE dbo.OrderDetailTBL
SET ShippingPhone = #Phone
WHERE OrderDetailID = #OrderDetailID
FETCH NEXT FROM MY_CURSOR INTO #OrderDetailID
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
If you wants to update one column with random number between some range and having -Ve type too, then you can use the below code :
UPDATE DataBase.TableName
SET Column = ((4 * RAND()) - (4 * RAND()))
WHERE IndexColumn > 0; -- here I have taken range between 4 to -4
I am using a while loop in a stored procedure to update each row of my table but the update value remains the same for all rows.For instance,in my table the generated number is 2266 for all rows instead of a unique digit.
My stored procedure looks like this
DELIMITER ;;
CREATE PROCEDURE lesrows()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE lesrand INT DEFAULT 0;
SELECT COUNT(*) FROM students INTO n;
select(FLOOR(2000 + RAND() * (3000 - 2000) )) into lesrand;
SET i=0;
WHILE i<n DO
UPDATE students set student_number= lesrand;
SET i = i + 1;
END WHILE;
End;
;;
call lesrows();
Why is it inserting a constant number for all rows instead of a unique number for every row?.
The while statement sets the whole table's student_number's the lesrand on every single iteration. You want a new random number of each iteration (inside the loop) and you want to select students one-by-one using WHERE with your variable i
Something like this:
SET i=0;
WHILE i<n DO
select(FLOOR(2000 + RAND() * (3000 - 2000) )) into lesrand;
UPDATE students set student_number= lesrand WHERE student_ID = i;
SET i = i + 1;
END WHILE;
I haven't tested it, but it looks like lesrand is only assigned once. Have you tried moving select(FLOOR(2000 + RAND() * (3000 - 2000) )) into lesrand; into the while loop like this:
DELIMITER ;;
CREATE PROCEDURE lesrows()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE lesrand INT DEFAULT 0;
SELECT COUNT(*) FROM students INTO n;
SET i=0;
WHILE i<n DO
select(FLOOR(2000 + RAND() * (3000 - 2000) )) into lesrand;
UPDATE students set student_number= lesrand;
SET i = i + 1;
END WHILE;
End;
;;
call lesrows();
And why are you using a stored procedure. Wouldn't UPDATE students SET student_number = FLOOR(2000 + RAND() * (3000 - 2000)) have the same result?