Within my database, I have a large number of tables which contain dates. These are expiry dates to be precise.
Currently, I perform the following commands to remove any rows which are older than a specified date using:
DELETE FROM tablename WHERE DATE(datepoint) < '2019-03-18'
1) Is there a way I can instead search and delete from an entire database instead of manually changing the table name and running the command each time?
You could use a PHP function, Anyway I wouldn't recommend deleting any records, just filter your queries for the last 3 months only
Perhaps consider having expiry dates in their own table EXPIRY_DATES. It sounds like it could be an important concept in your domain. Then have your other tables point to the correct expiry date using a foreign key. Using on delete cascade rules from EXPIRY_DATES would clean out records from all child tables when you delete one expiry date from EXPIRY_DATES.
you shoould use procedure (or function):
Define a procedure :
mysql> CREATE PROCEDURE delete_from_table(OUT table_name char(20))
-> BEGIN
-> delete from table_name WHERE DATE(datepoint) < '2019-03-18';
-> END//
mysql> delimiter ;
CALL procedure :
mysql> CALL delete_from_table(#table1);
mysql> CALL delete_from_table(#table2);
mysql> CALL delete_from_table(#table3);
Related
Within a MySQL 8 database I have two identical tables in different schemas with one being used as a staging table for its equivalent production table. The tables contain 200+ columns with more to be added in the future, making explicitly defining values for column names difficult.
I need to INSERT or UPDATE values in the production table with those in the staging table using an AFTER INSERT trigger, where all values of a row within the production table are replaced upon the existence of a duplicate PRIMARY KEY. Note that the production table has its PRIMARY KEY defined.
After this, I should delete all rows from the staging table.
Here is the code I have tried:
CREATE TRIGGER stage.my_table_after_insert AFTER INSERT ON my_table
FOR EACH ROW
BEGIN
REPLACE INTO prod.my_table
SELECT * FROM new;
DELETE FROM stage.my_table
END
I don't get why are You doing so, but why arent you doing something like:
REPLACE INTO prod.my_table
SELECT * FROM stage.my_table;
DELETE FROM stage.my_table;
You cant alter a table within its own contained trigger. Additionally, using a trigger will execute all SQL statements once per row (inefficient in this case). Therefore, a procedure is instead used to perform the required functions, using the following:
DELIMITER $$
CREATE PROCEDURE stage.load_data()
BEGIN
REPLACE INTO prod.my_table
SELECT * FROM stage.my_table;
DELETE FROM stage.my_table;
END$$
DELIMITER ;
Let's say that I have a series of tables in mysql, and some of them are dependent on other tables (so if I didn't want to force delete, i would have to delete them in order). Now let's say I had a little script to delete them in order...Now let's say I wanted to run that in mysql workbench, and better yet have a function that took in a parameter (like userId) and did the above... How would I do such a thing in Mysql workbench in a way that I could easily retrieve and run the code (like for example if I wanted to delete a user and all the other objects associated with the user.)
You can use a stored procedure
DELIMITER //
CREATE PROCEDURE delete_user(IN _user_id INT)
BEGIN
START TRANSACTION;
DELETE FROM user_data WHERE user_id = _user_id;
-- your other delete statements go here in a proper order
DELETE FROM users WHERE id = _user_id;
COMMIT;
END//
DELIMITER ;
Sample usage:
CALL delete_user(2); -- delete a user with id = 2
Here is a SQLFiddle demo
It is possible to use a version control system with mysql databases?
Or, is there a version control system already implemented?
I want to say e.g.: SELECT foo FROM bar WHERE version = X
Whereeby version is a mysql internal colum with last update date.
Very late response... similar to Ruben's suggestion, I have setup triggers to update a version_control table to increment version number every time there is an INSERT, UPDATE & DELETE.
I laid out the steps on my site mradamfrancis.tumblr.com
** update **
I’ve decided to use triggers to assist with version control. Here’s how…
I have a table containing players, if there are changes (INSERT, DELETE, or UPDATE) I want to increment the version number in my version_control table.
This is how the version_control table looks:
version_id (key), table_name (varchar), version (integer)
I then create 3 triggers on the players table, one for INSERT, DELETE & UPDATE.
INSERT:
delimiter //
CREATE TRIGGER `player_table_INSERT` AFTER INSERT ON `players`
FOR EACH ROW BEGIN
UPDATE version_control SET version=version+1 WHERE table_name=’players’;
END;//
delimiter ;
DELETE:
delimiter //
CREATE TRIGGER `player_table_DELETE` AFTER DELETE ON `players`
FOR EACH ROW BEGIN
UPDATE version_control SET version=version+1 WHERE table_name=’players’;
END;//
delimiter ;
UPDATE:
delimiter //
CREATE TRIGGER `player_table_UPDATE` AFTER UPDATE ON `players`
FOR EACH ROW BEGIN
UPDATE version_control SET version=version+1 WHERE table_name=’players’;
END;//
delimiter ;
** I have additional SQL statements in the FOR EACH section of the trigger, hence I’ve used delimiter (1st line and last line) along with BEGIN & END.
You could also define extra tables for logging. For instance if you already have a table news, you can duplicate it as news_log. then add columns for logging data such as: modified date, action (update, delete, add) and so on.
next you define triggers on the original tables that will insert the data into your logging table. for instance when you update a record in you news table the news_log_trigger that you define is executed and a new record is inserted into new_log with the action value "UPDATE" and the current date as modified date.
for more info on mysql triggers:
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
In case you want to do this for every project you can problably write a generic stored procedure to do the actual logging. that way you can reuse it and you only have to define the triggers and logging tables.
To futher clarify i was trying to create a trigger that checks a table for a number in sql.
If it finds said number then it erases that entire row.
It uses a separate table of names to check.
I thought it be could done using a join but have had no luck.
So it would look like this I suppose if(tb1.name = tb2.name) then DELETE row.
I'm sorry if the formatting is off.
EDIT; I am using phpmyadmin so some of the the code may be missing but here is the code from my latest "attempt"
It uses on INSERT and time is set to AFTER
SELECT * FROM flights WHERE NOT EXISTS (SELECT * FROM no fly list WHERE PassengerId.Id = Passenger.Id)
have not added the DELETE as of now but the work is somewhat ongoing
Assuming that flight and dnf both have passenger_id column that uniquely identifies a passenger of interest then your trigger might look like this
DELIMITER $$
CREATE TRIGGER dnf_insert AFTER INSERT
ON dnf
FOR EACH ROW BEGIN
DELETE FROM flights WHERE passenger_id = NEW.passenger_id;
END$$
DELIMITER ;
If you post DDL (create table statements) for all relevant tables we can refine the query
I am wondering if it is possible to perform a SQL query then update another table with the generated ID and continue through all of the rows?
I have this SQL query that works but what I need to do is after each row is added to cards to then update merged.cars_id with the last generated ID so they are linked. normally I would do this with PHP but ideally I would like to just do it with MySQL if possible.
MAIN QUERY
INSERT INTO cards (first_contact_date, card_type, property_id, user_id)
SELECT first_contact_date, 'P', property_id, user_id FROM merged
THEN I NEED WITH MATCHING ROWS (Roughly)
UPDATE merged SET merged.card_id = LAST_INSERT_ID (FROM ABOVE) into the matching record..
Is something like this possible and how do I do it?
I would recommend using MySQL triggers to do this
http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
A trigger is a function that will be executed AFTER or BEFORE the INSERT or DELETE or UPDATE is done over any record of your table.
In your case you need to do a AFTER INSERT on cards that just updates the merged table. Make sure its AFTER insert as you wont be able to access the new row's ID otherwise.
The code would look something like this, assuming the id field from the cards table its named "id"
delimiter |
CREATE TRIGGER updating_merged AFTER INSERT ON cards
FOR EACH ROW BEGIN
UPDATE merged SET card_id = NEW.id;
END;
|
delimiter ;
May I suggest Stored Procedures?
http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html
--EDIT--
Ah yes, triggers. For this particular situation, Jimmy has the answer. I will leave this post for the sake of the link.
I would set up a trigger to do this. For mysql, read http://dev.mysql.com/doc/refman/5.0/en/triggers.html. This is what triggers are designed to handle.