Execute query based on number of rows? - mysql

I'm not too great with MySQL, but I'm trying to create a trigger so that whenever a row is inserted, if the total count of rows in the table is bigger than 10 a certain row is deleted.
What I'm looking for, without the trigger syntax, is something like this:
IF (SELECT COUNT(*) FROM table) > 10 THEN
//do some stuff
END IF;
However that does not seem to be acceptable syntax. How should I go about doing this?

DELIMITER &&
CREATE TRIGGER trigger_name AFTER INSERT ON table_name FOR EACH ROW
BEGIN
DECLARE x INT;
SET x = (SELECT count(*) FROM table_name);
IF x > 10 THEN
DELETE FROM table_name where condition;
END IF;
END&&
DELIMITER ;

select count(1) into #cnt from table;
if (#cnt > 10) then
// do some stuff
end if;
instead of #cnt you can used declared variable

Related

How can I prevent insertion into a table through trigger?

I've to prevent the insertion into table when the number of rows having colour as Red exceeds 100. Here's the code that i've written, just dont know what to write in the blank.
CREATE TRIGGER onRegisterInsert BEFORE INSERT ON table_name FOR EACH ROW
BEGIN
DECLARE n INT DEFAULT 0;
IF New.Colour='Red' THEN
SELECT COUNT(*) INTO n FROM table_name WHERE Colour='Red';
if n > 100 THEN
---
END IF
END IF
END
I thought of writing SIGNAL SQLSTATE '45000' to prevent insertion but i dont want to throw an error, because i'm inserting a list of data and if i throw an error the insertion of data after this will also be stopped.
I also thought of writing an after insert trigger instead of before.
DELIMITER //
CREATE TRIGGER onRegisterInsert After INSERT ON table_name FOR EACH ROW
BEGIN
IF New.Colour='Red' THEN
SELECT COUNT(*) INTO #count FROM table_name WHERE Colour='Red';
IF (#count >= 100) THEN
delete from table_name new;
END IF;
END IF;
END //
but this code too gives an error.
One thing you could do is use INSERT IGNORE in the calling app instead of INSERT.

MaxRow Trigger not working in mysql

I wanted to write a trigger which deletes the oldest DB entry if a new one is inserted and the rowcount is larger than 3600 rows. Unfortunately, there is a error(1064) in line 7, but I don't know how to fix it. The column time if defined by using DATETIME in mysql.
CREATE TRIGGER maxRows BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
IF ((SELECT COUNT(*) FROM table1) = 3600) THEN
DELETE FROM table1
ORDER BY time ASC
LIMIT 1;
END IF;
END;
As you have some DML sentences inside your trigger, try changing the delimiters
DELIMITER $$
CREATE TRIGGER maxRows BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
IF ((SELECT COUNT(*) FROM table1) = 3600) THEN
DELETE FROM table1
ORDER BY time ASC
LIMIT 1;
END IF;
END;
END $$
DELIMITER ;

Converting mysql trigger to pl/sql trigger

I have created a trigger for my mysql project previously and it was working well. However, I am trying to change this trigger to make suitable for pl-sql(oracle). This is my original code which works in the mysql:
DELIMITER $$
CREATE TRIGGER course_title_delete AFTER DELETE on Course
FOR EACH ROW
BEGIN
DECLARE rownumber INT;
SET rownumber = (SELECT COUNT(*) FROM Course
WHERE Course_code=old.Course_code);
IF rownumber = 0
THEN
DELETE FROM Course_title
WHERE Course_title.Course_code=old.Course_code;
END IF;
END$$
DELIMITER ;
And this one is the same code which I have tried to convert pl-sql format. However it is not working, when I upload as a script and try to run it in apex.
CREATE OR REPLACE TRIGGER course_title_delete
AFTER DELETE ON course
FOR EACH ROW
BEGIN
DECLARE rownumber INT;
SET rownumber = (SELECT COUNT(*) FROM course
WHERE course_code= :old.course_code);
IF rownumber = 0
THEN
DELETE FROM course_title
WHERE course_title.course_code:=:old.course_code;
END IF;
END;
/
At the very least, you have a syntax error in this line:
DELETE FROM course_title
WHERE course_title.course_code:=:old.course_code;
----------------------------------^
That should just be =.
Also, in Oracle, the DECLARE goes before the BEGIN, not after.
Also, in Oracle, this line:
SET rownumber = (SELECT COUNT(*) FROM course
WHERE course_code= :old.course_code);
should be:
SELECT COUNT(*) INTO rownumber
FROM course
WHERE course_code = :old.course_code;
Well, actually, the is the correct syntax for what you are expressing. But, you should be using NOT EXISTS rather than COUNT(*) in both databases.
In both databases, I think you can replace this trigger with a cascading delete foreign key constraint. Also, you can simplify the logic to eliminate the if:
CREATE OR REPLACE TRIGGER course_title_delete
AFTER DELETE ON course
FOR EACH ROW
BEGIN
DELETE FROM course_title
WHERE NOT ExISTS (SELECT 1
FROM course c
WHERE c.course_code = :old.course_code
) AND
course_code = :old.course_code;
END;

How do I randomly select 5% rows of each userid (column) in MySQL?

How do I randomly select 5% rows of each userid column using MySQL?
That is, mytable contains userid column, and I want to randomly check each user's 5% of entered rows. So the query should return 5% of each user's rows.
You can say:
SELECT * FROM mytable ORDER BY RAND() LIMIT 5
if you know there are 100 rows in the table.
If you don't know, you can try this query first to find out:
SELECT COUNT(*) FROM mytable
Otherwise, you can also try:
SELECT * FROM mytable WHERE RAND() < 0.05 ORDER BY RAND()
This selects approximately 5% of all rows (but it is a little random because it basically selects rows with 5% chance).
Otherwise, you can use subqueries:
SELECT * FROM mytable ORDER BY RAND() LIMIT (SELECT COUNT(*) FROM mytable)
I got the solution by using Events:
drop event OEAuditEvent;
DELIMITER $$
CREATE EVENT OEAuditEvent
ON SCHEDULE EVERY 1 SECOND
STARTS '2012-09-05 09:00:00'
DO
BEGIN
DECLARE a CHAR(20);
DECLARE b,c,d INT;
DECLARE done INT DEFAULT FALSE;
IF CURRENT_TIME() = '23:40:00' THEN
begin
DECLARE cur CURSOR FOR select OE_User,count(OE_User) from RNCM_Status where date(OE_Date)=CURDATE() group by OE_User;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO a, b;
SET c=ceil((b*5)/100);
IF done THEN
LEAVE read_loop;
ELSE
insert into OE_Audit(MDN,CAF,UploadedDate,OEUser,OEDate,UserCount,QCCount,intime) select MDN,CAF,UploadedDate,OE_User,OE_Date,b,c,now() from RNCM_Status where OE_User=a and date(OE_Date)=CURDATE() order by rand() limit c;
END IF;
END LOOP;
CLOSE cur;
end ;
END IF;
END $$
DELIMITER ;

How to create a table with consecutive numbers

I need a helper table with only one int(11) column, that contains a row for each consecutive number from 1 to a given max. Can this be done with pure SQL?
Example:
INSERT INTO `helper`('itnum') VALUES (1),(2),(3),...(999999),(1000000);
I need a statement like this, but without explicitly listing all the entries to be made.
How about something like this:
DELIMITER |
DROP PROCEDURE IF EXISTS insert_helper_records |
CREATE PROCEDURE insert_helper_records(a_max INTEGER)
BEGIN
DECLARE v_iteration INTEGER;
SET v_iteration := 1;
insert_loop: LOOP
INSERT INTO helper(itnum) VALUES (v_iteration);
SET v_iteration := v_iteration + 1;
IF v_iteration = a_max THEN
LEAVE insert_loop;
END IF;
END LOOP;
END |
DELIMITER ;
Then call it however you want like:
SELECT insert_helper_records(999999) FROM DUAL;
i think to do this, you have to execute your insert inside a loop in your SGBD procedure, or outside (php script, ...).