MySQL: update without changing data, possible? - mysql

Is it possible in MySQL to update a row, without changing any data?
I just need a trigger to do its work, but the data should not be changed.
Of course I could do an update and then another update, but the trigger is quite slow (deletes and inserts 500 rows everytime) and I have to update thousands of rows, so I'd rather not do it twice.
I could also just update a dummy field with NOW(), but I'm just curious if it's possible without 'tricks'.

How about:
UPDATE table SET id=id WHERE ...

You should just be able to run an UPDATE command with the same data that already exists in the row. No data will change, but the trigger will still fire.

Related

How to automatically run a query when a table is amended by INSERT/UPDATE/DELETE?

I have a query which basically "syncs" all the data from a table in one database, to a replicated table in another database.
Here is the simple query:
TRUNCATE TABLE [Database2].[dbo].[USER_SYNC]
INSERT INTO [Database2].[dbo].[USER_SYNC]
SELECT * FROM [Database1].[dbo].[USER]
Now, after some research, I had a look into using a trigger to do this, however, I read up that stored procedures and heavy queries such as this should not be used within a trigger.
Therefore, what is the best way in which I can automatically run this query from within SQL, whenever a record in database1 is inserted, amended or deleted?
And if what I read up about triggers was incorrect, then how would I go about creating one for my procedure? Thanks.
If you need to sync tables you do not need to truncate one every time on update, delete or insert.
Create identical copy of user table.
Create on update, on delete, on insert triggers on the original user table.
In the trigger update, delete or insert to the duplicate table only one row at a time - the one that was updated, deleted or inserted to the original user table. This will not be a heavy query.
UPDATE:
http://www.mysqltutorial.org/create-the-first-trigger-in-mysql.aspx
http://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html

UPDATE my_table doesn't work correctly

I'm using the following query to replace old link with a new one:
UPDATE my_table SET file = 'link' WHERE my_table.file ='old_link';
In my tests I can't duplicate that and I'm not sure what's wrong with that query, but apparently sometimes it leaves the old entry and inserts a new one instead of updating!
mysql ver:
5.6.12-56 Percona Server, table type: innodb
The query looks fine to me. UPDATE should never create new rows, only modify existing rows. The problem is probably in another part of the code.
Although an UPDATE won't fire an insert in its own, there could exist triggers in the database that would fire an INSERT whenever a record gets updated.
Here are some links that you should check:
CREATE TRIGGER Syntax
Trigger Syntax and Examples

UPDATE Same Row After UPDATE in Trigger

I want the epc column to always be earnings/clicks. I am using an AFTER UPDATE trigger to accomplish this. So if I were to add 100 clicks to this table, I would want the EPC to update automatically.
I am trying this:
CREATE TRIGGER `records_integrity` AFTER UPDATE ON `records` FOR EACH ROW SET
NEW.epc=IFNULL(earnings/clicks,0);
And getting this error:
MySQL said: #1362 - Updating of NEW row is not allowed in after trigger
I tried using OLD as well but also got an error. I could do BEFORE but then if I added 100 clicks it would use the previous # clicks for the trigger (right?)
What should I do to accomplish this?
EDIT - An example of a query that would be run on this:
UPDATE records SET clicks=clicks+100
//EPC should update automatically
You can't update rows in the table in an after update trigger.
Perhaps you want something like this:
CREATE TRIGGER `records_integrity` BEFORE UPDATE
ON `records`
FOR EACH ROW
SET NEW.epc=IFNULL(new.earnings/new.clicks, 0);
EDIT:
Inside a trigger, you have have access to OLD and NEW. OLD are the old values in the record and NEW are the new values. In a before trigger, the NEW values are what get written to the table, so you can modify them. In an after trigger, the NEW values have already been written, so they cannot be modified. I think the MySQL documentation explains this pretty well.
Perhaps you could write two separate statements in that transaction
update record set clicks=...
update record set epc=...
or you could put them inside a function, say updateClick() and just call that function. By doing it this way you can easily alter your logic should the need arise.
Putting the logic inside a trigger might create a situation where debugging and tracing are made unnecessarily complex.

MySQL: UPDATE trigger. Obtain the value of a column used in UPDATE's where clause if it fail to match any row?

MySQL: In update trigger's body, can I obtain the value of a column that is specified in the where clause of the triggering query if the where clause does not match any rows at all?
I have to do the following, but NOT USING direct query such as ON DUPLICATE KEY UPDATE so on:
If I have:
UPDATE my_table SET idiotism_level=5 WHERE name='Pencho'
... and the where clause match NO ROWS, I'd want to automatically trigger an insertion of a row having name='Pencho' before the update, and then the UPDATE would presumably match, and work properly.
Is it possible ?
This could be make in a RULE in other database systems (PostgreSQL), that does not exists in MySQL. It's a Rule and not a trigger as you should analyse the query and not the result of the query.
But for MySQL you can make pre-query jobs by using MySQL-Proxy. You should be able to alter your update query and build an insert, By running some 'check row exists' extra query from the MySQL-Proxy (I'm not saying this is a nice solution, but if you have no way to make the code to act better you can fix it at this level).
No. An update trigger fires once for each row that gets updated, not once for each update command that's executed. There's no way to make the trigger fire if nothing is updated. You would need to handle this in your application by checking the number of updated rows returned by your query.
If name has a unique index on it you can use REPLACE
REPLACE INTO my_table (idiotism,name) VALUES ( 5,'Pencho');

Performing an UPDATE or INSERT depending whether a row exists or not in MySQL

In MySQL, I'm trying to find an efficient way to perform an UPDATE if a row already exists in a table, or an INSERT if the row doesn't exist.
I've found two possible ways so far:
The obvious one: open a transaction, SELECT to find if the row exists, INSERT if it doesn't exist or UPDATE if it exists, commit transaction
first INSERT IGNORE into the table (so no error is raised if the row already exists), then UPDATE
The second method avoids the transaction.
Which one do you think is more efficient, and are there better ways (for example using a trigger)?
INSERT ... ON DUPLICATE KEY UPDATE
You could also perform an UPDATE, check the number of rows affected, if it's less than 1, then it didn't find a matching row, so perfom the INSERT.
There is another way - REPLACE.
REPLACE INTO myTable (col1) VALUES (value1)
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted. See Section 12.2.5, “INSERT Syntax”.
In mysql there's a REPLACE statement that, I believe, does more or less what you want it to do.
REPLACE INTO would be a solution, it uses the UNIQUE INDEX for replacing or inserting something.
REPLACE INTO
yourTable
SET
column = value;
Please be aware that this works differently from what you might expect, the REPLACE is quite literally. It first checks if there is a UNIQUE INDEX collision which would prevent an INSERT, it removes (DELETE) all rows which collide and then INSERTs the row you've given it.
This, for example, leads to subtle problems like Triggers not firing (because they check for an update, which never occurs) or values reverted to the defaults (because you must specify all values).
If you're doing a lot of these, it might be worth writing them to a file, and then using 'LOAD DATA INFILE ... REPLACE ...'