One of our tables has been maligned
/*edit as per commented request
On doing an update to a specific column I accidentally neglected to specify for which row I wish to make this change and set the offending value for every row in the table.
*/end edit
but we have a very recent backup, however not so recent that other tables won't lose data if we do a total database restore.
I'm wondering what the procedure is (assuming there is one) of copying the contents of a given table from one database to another.
The largest problem is that I can't just drop the offending table and replace it as it has rows that are indexed by id into other tables. This won't be a problem if we just take the values from the identical rows in the back-up and bring them over (since the row ids wouldn't change).
It's unclear what exactly has gone wrong with your data. But I'm thinking maybe just a column or two has got messed up. As you said, you just want to copy over the data from the old table, based on the id column.
Assuming you've imported the backup database as "olddb" and the current one is named "newdb":
UPDATE newdb.yourtable newtable, olddb.yourtable oldtable
SET newtable.somecolumn = oldtable.somecolumn
WHERE newtable.id = oldtable.id
Use mysqldatadump for that particular table, and then feed that into the other database.
You can edit the dump file prior to redaing it in to the target table.
See: https://dba.stackexchange.com/questions/9306/how-do-you-mysqldump-specific-tables
Related
Is it the correct approach? Any suggestions to make it better?
Below is screenshot of employee table and its shadow table where the tl_name and dept fields may change and currently using shadow table to track all changes.
Records are inserted/updated in Main table and it gets copied to shadow table with help of data macro.
all the records in the shadow table have to be approved/rejected by superuser
Main table will have updated alignment and shadow table will have entire history of changes for any employee.
When a record is added/updated in Main table via userform, a copy of record will be created in shadow table which has to be approved by admin.
When a record is added/updated in Main table via userform, is_active field will be set as false and once it is approved by admin this will be updated to true.
As I understand your requirements:
Changed/inserted data should be immediately visible to everyone, with a visible flag for un-approved data.
This is reasonable, if you work under the assumption that the majority of changes are correct and will be approved (hopefully true ;) ).
I think you are missing:
If a change is rejected, the data in Main table should be automatically reverted to the most recent approved state.
Otherwise the Main table stays in a (sort of) undefined state forever, with is_active = False and (apparently) wrong data.
This can be done with your audit table design. Find the latest approved entry for this emp PK, and use its data.
But if the number of columns that are audited may change in the future, you might consider an approach with two tables, as in this project: https://autoaudit.codeplex.com/documentation
AuditHeader Table
This table is inserted with one row everytime one record is inserted,
updated or deleted in a table that has been setup to use the AutoAudit
system.
AuditDetail Table
This table is related to AuditHeader and is inserted with one row for
each column that is changed during an insert or update operation and
for each column during a delete operation.
If you save old + new values with every change, you can revert to "old" state just from the current Audit entry.
And a structure change of Main table (or if you decide that e.g. users can edit emp_name too) doesn't need a structure change of the Audit table, because every audited column in Main is mapped to a row in AuditDetails instead of a column.
Edit: Additional advantage:
In your sample data you have marked the changed values in red. Obviously an Access table doesn't work like that. If you want to keep this information ("which column(s) exactly was edited?"), you would need an additional column in the Audit table.
This would be covered by AuditDetail, since it contains each change with old + new value.
Wondering if someone can kindly help. I am sure I have done this before but I can't remember how!
I have two tables
database.users - old
database.site_users - new
Both have matching columns but the OLD table has more custom columns that aren't used anymore.
Can I copy the users from the old database to the new database, but ensuring it only copies the data from columns that still exist?
At the moment I get a load of errors about the column count doesn't match etc.
Thank you to anyone who can help :)
I would have just commented, but I can't yet.
To do this I think you would either need to:
1. Make sure you have the same columns on both tables, perform the transfer and then delete the unneeded columns on the new table.
2. Write a script or query that Selects all the data from the old table and inserts it into the new table in the required format.
3. Export the data, make the required changed to the file and then re-import it (this would be tedious).
EDIT: This seems to have been answered here How to move data between 2 tables / with different columns in different databases
Using:
INSERT INTO B.foo1 (id, col11, col3)
SELECT id,col1,col3 FROM A.foo;
My situation is this:
I have a table, call it x.
Every time a row is updated or deleted, a copy of the old row should be inserted into x_history.
Additionally x_history will have its' own auto-incrementing id column, call that histid.
It is very important to have its' own id column as this will give us the flexibility to build version restore functionality.
I have 100+ tables to apply this to so I'm looking for a generic trigger that can be used for any table to backup one row into a history table. Only the 2 table names should vary from trigger to trigger. Specifying all column names is really not what I'm looking for.
I need to do this in MySQL but have added MSSQL too - I know both so can convert between one and the other easy enough.
Usually, Triggers are not the optimal solution for such purposes.
If possible, you might want to consider changing your database design.
Normally, a better way to handle such things are keeping the hole history in the source table, And have a status column that tells you for each row if it's deleted, updated, or current.
I have little to no experience with MySql, but I have been working with Sql server for the past 7 or 8 years, so what I'm about to say is true for sql server, but may be different for MySql.
If you choose to go with the triggers approach, keep in mind that after update triggers will execute even if the update does not change the row data (e.g update tableName set col1 = 1 where idCol = 4, the update trigger will be executed even if the col1 value before the update was 1, so no data was changed.)
For SqlServer, you might want to consider a common history table, that has only 6 columns:
1. Identity column
2. Table name column
3. Row Id column (original id from the original table)
4. Row Status column (e.g updated, deleted)
5. Action date (the date the row was copied to the history table)
6. Row content column (this should be an XML datatype (not sure if MySql has such dataType))
and then all you have to do is to use "SELECT * FROM deleted/inserted FOR XML AUTO" to create the content for the 6th. column.
Assuming I have the following table named "contacts":
id|name|age
1|John|5
2|Amy|2
3|Eric|6
Is there some easy way to check whether or not this table changes much like how a sha/md5 hash works when getting the checksum for a file on your computer?
So for example, if a new row was added to this table, or if a value was changed within the table, the "hash" or some generated value shows that the table has changed.
If there is no direct mechanism, what is the best way to do this (could be some arbirary hash mechanism, as long as the method puts emphasis on performance and minimizing latency)? Could it be applied to multiple tables?
There is no direct mechanism to get that information through SQL.
You could consider adding an additional LastModified column to each row. To know the last time the table was modified, select the maximum value for that column.
You could achieve a similar outcome by using a trigger on the table for INSERT, UPDATE and DELETE, which updates a separate table with the last modified timestamp.
If you want to know if something has changed, you need something to compare. For example a date. You can add a table with two columns, the tablename and the timestamp, and program a trigger for the events on the table you are interested to control, so this trigger will update the timestamp column of this control table.
If the table isn't too big, you could take a copy of the entire table. When you want to check for changes, you can then query the old vs. new data.
drop table backup_table_name;
CREATE TABLE backup_table_name LIKE table_name;
INSERT INTO backup_table_name SELECT * FROM `table_name`;
I have designed a page using PHP, JavaScript and MYSQL, where it holds id(Auto incremented) images, names and so on. every thing works fine, i can insert, update or delete the records with click on respective buttons. what i have noticed that once a record deleted and when i try to insert a new record, it gets placed exactly after recently deleted record. for example. if i have 18 records, i delete record # 14 and insert a new record which obviously will be record # 19, it will be place after deleted record which was #14. is there anyway to force the insert to place the new record at the end of the table (after last record #19)? i don't want to get into phpMyAdmin and use Alter table order by...
when using select i have no problem as i'm using ORDER BY.. so that it displays every thing as i want.
Appreciating all your help.
Fardin
By definition, SQL tables have no natural order. Relying on the natural order that some MySQL table managers provide is going to lead to very fragile code. Please consider sticking with the SQL standard and ordering your rows on retrieval.
You cannot control how MySQL controls the recycling of deleted-record space.
Here is a comment from MySQL that says, essentially, the same thing: http://forums.mysql.com/read.php?108,41767,41836.