I want to create a history table for actions done inside the database, the easiest way i thought was to create a history table that was updated through a trigger on each table modified.
I would like to also include a userId so I can identify who changed it as well, but when i do my inserts/delete statements etc, I would also need to add in the userId (which kinda has no relevance to the operation), in order to use the history table as i described.
So is there a way to just put the userId into a SQL statement? Or should I just actually do the history table as a separate query after doing my insert / delete statements, rather than using a trigger
Thanks in advance
Grant
It will be the best practices to add user column in main table which we can easily use in trigger to inserts/delete/update in history table.
Related
In MySQL, which is a better practice? Always use "CREATE TABLE IF NOT EXISTS", or check first the existence of the table using "SHOW TABLES LIKE" before making the table?
I have to regularly save a page where the table for it may or may not be there (sometimes, it is deliberately deleted when not in use). Previously, I used to do "SHOW TABLES LIKE" to check if that table exists before I insert new entries. But I changed it to "CREATE TABLE IF NOT EXISTS". Either way, I just do a "INSERT .. ON DUPLICATE UPDATE" to add new or update existing data.
I don't know how to benchmark this, which is why I am asking.
Performance isn't critical with these operations.
The key aspect is race conditions. If you use CREATE TABLE IF NOT EXISTS you know it will happen or it won't. If two threads happen to be doing this statement one will succeed and the other won't be negatively affected.
If a SHOW TABLE LIKE was used in both threads, both could detect the table didn't exist, and upon trying to create the table, one would fail.
So use CREATE TABLE IF NOT EXISTS to mitigate race conditions. Also in general is better to use a database provided feature than roll your own.
CREATE TABLE IF NOT EXISTS is option provided by MySQL and good to use. If table will not exist this statement will create else will skip.
other end, if you first check table existence by show table like then either skip or create as per result of condition/check. Ultimately you are increasing one step or runtime of you script or program for same functionality which you can achieve in single step.
Is there any way to detect when an ALTER TABLE statement is executed in MySQL? For example, if the following statement were executed on some_table, is there any way to detect that the column name changed from column_name_a to column_name_b and log it in another table in the DB?
ALTER TABLE `some_table`
CHANGE COLUMN `column_name_a` `column_name_b` VARCHAR(255) NULL DEFAULT NULL;
Thanks.
To my knowledge it is unfortunately not possible to put triggers on the INFORMATION_SCHEMA tables, since they are strictly spoken views and triggers can't be made to work on views. If triggers would be possible on the INFORMATION SCHEMA, then you could have a trigger on updates of the INFORMATION_SCHEMA.COLUMNS table to identify name changes.
However, what you can do is one of the following things:
option 1) Maintain a real table with all column names. Then create a function that checks for a discrepancy between the INFORMATION_SCHEMA.COLUMNS table abd your table. If there is one, you know the name has changed. You need to copy over the new name to your column name table and do whatever else you wanted to do upon name change.
The function to check for discrepancies then must be run periodically via the mysql scheduler in order to detect name changes as quickly as possible. Note that this is not a real time solution. There will be a lag between the ÀLTER TABLE command and its detection. If this is unacceptable in your scenario you need to go with
option 2) Do not call ÀLTER TABLE directly, but wrap it in a function. Within this function you can also call other functions to achieve what you need to achieve. If may be worth while to formulate the needed steps in a higher programming language that you use to drive your application. If this is not possible, you will be limited to the possibilities that are offered in functions/procedures in the mysql environment.
Sorry to not have a simpler way of doing this for you.
I need to put all the result of a query to a temporary table then select from it, but due to the nature of the temporary table, I cannot refer to it more than once in the same query. So is it ok to create a uniquely named (regular) table for this and drop it after the query is completed? Or is there a better way to do this?
I tried using Derived tables but I cannot access it from different blocks.
It's not necessarily a matter of whether it's good practice or not. Whether it's a regular table, temporary table or derived table they all serve a purpose when trying to accomplish a task. Therefore, creating a regular table or a temporary table all depends on you and what you want your application to accomplish at the end of the day.
But based on your problem it seems that you might need to create a regular table in this situation since you require access to the table more than once, and you can drop the table after you're finished with it.
Is there a way to do this?
In case the DBMS command history got cleaned or, in my case, when many ALTER TABLE were used in the course of time.
I'm using MySQL.
Yes, it is as simple as
SHOW CREATE TABLE yourtable;
This will include all the subsequent ALTER TABLE statements. You cannot retrieve the table's original state.
Here is the relevant documentation
I know that triggers can be used on insert, update and delete, but what about a trigger (or sort of) on a select statement. I want to use a trigger to insert data on a table B when it is selected an existent record on a table A, it could be possible?.
Thanks in advance.
You should design your application so that database access occurs only through certain methods, and in those methods, add the monitoring you need.
Not exactly a trigger, but you can:
CREATE FUNCTION myFunc(...) BEGIN INSERT INTO myTable VALUES(...) END;
And then
SELECT myFunc(...), ... FROM otherTable WHERE id = 1;
Not an elegant solution, though.
It is not possible in the database itself.
However there are monitoring/instrumentation products for databases (e.g. for Sybase - not sure about MySQL) which track every query executed by the server, and can do anything based on that - usually store the query log into a data warehouse for later analysis, but they can just as well insert a record into table B for you, I would guess.
You can write an application which will be monitoring the query log and doing something when a select occurs. A pretty crude way to solve the problem though...